2016-02-07 20 views
7

finalisiere. Ich habe versucht, einen klassischen Offline-Zahlungs-Gateway mit Sylius zu implementieren (sylius/sylius-Standard, v0.16) .Wie man eine Bestellung fertigstellt, wenn ich Offsite-Payment-Gateway mit Sylius 0.16 und Payum

Bisher habe ich dies in Build mein Bundle() -Methode:

public function build(ContainerBuilder $container) 
{ 
    /** @var PayumExtension $payum */ 
    $payum = $container->getExtension('payum'); 
    $payum->addGatewayFactory(new PayWayOffsiteGatewayFactory()); 
} 

Hier ist meine config.yml.

sylius_payment: 
    gateways: 
     payway_offsite: PayWay 

payum: 
    gateways: 
     payway_offsite: 
      payway_offsite: 
       secret_key: %tcompayway.secret_key% 
       shop_id: %tcompayway.shop_id% 
       username: %tcompayway.username% 
       password: %tcompayway.password% 
       sandbox: %tcompayway.sandbox% 

Die% compayway *% Felder sind in Ordnung, natürlich konfiguriert, Hüpfen dieser Teil. Dann habe ich in meiner PayWayOffsiteGatewayFactory Klasse:

class PayWayOffsiteGatewayFactory extends AbstractGatewayFactory 
{ 
    /** 
    * {@inheritdoc} 
    */ 
    public function getName() 
    { 
     return 'payway_offsite'; 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function addConfiguration(ArrayNodeDefinition $builder) 
    { 
     parent::addConfiguration($builder); 

     $builder->children() 
      ->scalarNode('secret_key')->isRequired()->cannotBeEmpty()->end() 
      ->scalarNode('shop_id')->isRequired()->cannotBeEmpty()->end() 
      ->scalarNode('username')->isRequired()->cannotBeEmpty()->end() 
      ->scalarNode('password')->isRequired()->cannotBeEmpty()->end() 
      ->booleanNode('sandbox')->defaultTrue()->end() 
      ->end(); 
    } 

    /** 
    * {@inheritDoc} 
    */ 
    protected function getPayumGatewayFactoryClass() 
    { 
     return 'WebBurza\PaymentBundle\Payum\PayWay\PayWayGatewayFactory'; 
    } 

    /** 
    * {@inheritDoc} 
    */ 
    protected function getComposerPackage() 
    { 
     return 'webburza/tcompayway'; 
    } 
} 

Und die PayWayGatewayFactory Klasse:

class PayWayGatewayFactory extends GatewayFactory 
{ 
    /** 
    * {@inheritDoc} 
    * @throws \Payum\Core\Exception\InvalidArgumentException 
    */ 
    protected function populateConfig(ArrayObject $config) 
    { 
     $config->defaults(array(
      'payum.factory_name'   => 'payway_offsite', 
      'payum.factory_title'   => 'PayWay Offsite', 
      'payum.action.capture'   => new CaptureOffsiteAction(), 
      'payum.action.capture_null'  => new CaptureOffsiteNullAction(), 
      'payum.action.status'   => new StatusAction(), 
      'payum.action.convert_payment' => new ConvertPaymentAction(), 
     )); 

     if (false == $config['payum.api']) { 
      $config['payum.default_options'] = array(
       'secret_key' => '', 
       'shop_id'  => '', 
       'username'  => '', 
       'password'  => '', 
       'sandbox'  => true 
      ); 
      $config->defaults($config['payum.default_options']); 
      $config['payum.required_options'] = [ 
       'secret_key', 
       'shop_id', 
       'username', 
       'password', 
       'sandbox' 
      ]; 

      $config['payum.api'] = function (ArrayObject $config) { 

       $config->validateNotEmpty($config['payum.required_options']); 

       $api = new Api([ 
        'secret_key'=> $config['secret_key'], 
        'shop_id' => $config['shop_id'], 
        'username' => $config['username'], 
        'password' => $config['password'], 
        'sandbox' => $config['sandbox'], 
       ], $config['payum.http_client']); 

       return $api; 

      }; 
     } 
    } 
} 

Bisher ich habe den Eindruck, alles ist mehr weniger in Ordnung (korrigiert mich wenn ich 'Ich liege falsch). Ich habe es geschaffen, zu meinem CaptureOffsiteAction execute Methode zu erhalten:

public function execute($captureRequest) 
    { 
     RequestNotSupportedException::assertSupports($this, $captureRequest); 
     $model = ArrayObject::ensureArrayObject($captureRequest->getModel()); 

     $httpRequest = new GetHttpRequest(); 
     $this->gateway->execute($httpRequest); 

     if ($httpRequest->method === 'POST') { 
      $status = new GetHumanStatus($model); 

      if (isset($httpRequest->request['pgw_transaction_id']) && $httpRequest->request['pgw_transaction_id'] > 0) { 
       // mark this order id as paid, convert cart to order, etc. 

      } else { 
       // mark as failed/cancelled, redirect back to cart 
      } 
      return; 

     } 

     $model['successUrl'] = $captureRequest->getToken()->getTargetUrl(); 
     $model['failureUrl'] = $captureRequest->getToken()->getTargetUrl(); 
     $offsiteUrl = $this->api->getOffsiteUrl(); 

     $data = $this->api->prepareOffsitePayment($model->toUnsafeArray()); 
     $headers = ['application/x-www-form-urlencoded']; 

     throw new HttpPostRedirect(
      $offsiteUrl, 
      $data, 
      200, 
      $headers 
     ); 

    } 

Zuerst mal sehen, ob ich das richtig verstanden habe - sobald ich das Capture-Verfahren (execute-Methode) beginnen - Dinge wie erwartet, ich am Ende in der den unteren Teil der Methode, Erstellen von Erfolg und Misserfolg URLs, Vorbereitung Offsite-Zahlung, Hash und all das und schließlich auf dem Payment-Gateway über HttpPostRedirect mit korrekten Bestell-ID, Preis usw. landen. Dieser Teil ist in Ordnung.

Nach der Zahlung, nach der Rückkehr zum Erfolg URL, ich wieder in CaptureOffsiteAction :: execute und überprüfen Sie für pgw_transaction_id - wenn dies gesetzt ist, bedeutet es, dass ich von der Zahlung zurück und ich sollte entweder eine erfolgreich bezahlte Bestellung oder abgebrochen/fehlgeschlagene Zahlung.

Fragen sind:

  • bei erfolgreicher Zahlung - wie kann ich auf 'Schließen' den Auftrag

  • (konvertieren Warenkorb zu bestellen, wie gefangen Marke Zahlung usw.?) Ich sehe in anderen Zahlungs-Gateways, dass es viele andere Methoden gibt - sagen wir, dass nur Off-Site-Zahlung via Post-Redirect interessiert ist - was macht StatusAction? Und wann heißt es?

Bisher fand ich Payum (und PayumBundle) sehr verwirrend, ich habe es geschafft, in weniger als einem Tag 2 Offsite-Gateways zu implementieren mit OmniPay (auf anderen, nicht Sylius Projekte), aber kann nicht scheinen zu löse dieses Payum-Ding. :(

Jede Hilfe dankbar, danke im voraus

Antwort

2

Sorry für späte Antwort -. Ich schaffte es, um herauszufinden, wo ich schief gelaufen

ganze Idee ist, in aufeinanderfolgenden Aufrufen von Aktionen.In meinem Fall wäre, dass sein:

  • CaptureOffsiteAction
  • StatusAction

Mein erster Fehler dachte, dass Payum nur 1 Aktion für einen bestimmten Workflow verwendet. Die Dokumentation war ein wenig verwirrend (zumindest sah es für mich so aus), also habe ich nicht den Teil bekommen, in dem StatusAction nach der Rückkehr von PG tatsächlich den Bestellstatus behandelt.

Also von dem, was ich gesammelt:

  • CaptureOffsiteAction die Umleitung zu Payment-Gateway übernimmt und prüft Postbacks Anfrage auf Rückkehr
  • Dann nimmt StatusAction über und prüft, für die richtige Status der Auftrag abgeschlossen zu markieren, New oder fehlgeschlagen

Hier ist meine StatusAction Methode zum Beispiel auszuführen:

public function execute($request) 
{ 
    RequestNotSupportedException::assertSupports($this, $request); 

    $model = new ArrayObject($request->getModel()); 
    if (null === $model['EXECCODE']) { 
     $request->markNew(); 
     return; 
    } 

    if (Api::STATUS_SUCCESS === $model['EXECCODE']) { 
     $request->markCaptured(); 
     return; 
    } 

    $request->markFailed(); 
} 

Und hier ist der letzte CaptureOffsiteAction :: execute Methode:

public function execute($captureRequest) 
{ 
    RequestNotSupportedException::assertSupports($this, $captureRequest); 
    $model = ArrayObject::ensureArrayObject($captureRequest->getModel()); 

    $httpRequest = new GetHttpRequest(); 
    $this->gateway->execute($httpRequest); 

    if ($httpRequest->method === 'POST') { 
     // TODO: properly validate response signature here 

     if (isset($httpRequest->request['pgw_transaction_id'])) { 
      $model['EXECCODE'] = Api::STATUS_SUCCESS; 
     } else { 
      $model['EXECCODE'] = $httpRequest->request['pgw_result_code']; 
     } 

     return; 
    } 

    $model['successUrl'] = $captureRequest->getToken()->getTargetUrl(); 
    $model['failureUrl'] = $captureRequest->getToken()->getTargetUrl(); 
    $offsiteUrl = $this->api->getOffsiteUrl(); 

    $data = $this->api->prepareOffsitePayment($model->toUnsafeArray(), $captureRequest); 

    $headers = ['application/x-www-form-urlencoded']; 

    throw new HttpPostRedirect(
     $offsiteUrl, 
     $data, 
     200, 
     $headers 
    ); 
} 

Hope this einige von euch hilft! Prost.

+0

Ich habe 2 Tage gebraucht, um das herauszufinden und Paybox korrekt zu implementieren. Vielen Dank für Ihr Feedback. Und vergiss nicht, deine Antwort zu akzeptieren. – Aurel