2016-02-07 45 views
7

Próbowałem obalić sobie głowę, w jaki sposób zaimplementować klasyczną bramkę płatności w trybie offline przy użyciu Sylius (sylius/sylius-standard, v0.16) .Jak sfinalizować zamówienie podczas wdrażania zewnętrznej bramy płatniczej za pomocą aplikacji Sylius 0.16 i Payum

Do tej pory mam to w budowie mojego Bundle za() metoda:

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

Oto mój 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% 

Wartość% compayway *% pola są skonfigurowane w porządku oczywiście, pomijając ta część. Potem mam to w mojej klasie PayWayOffsiteGatewayFactory:

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'; 
    } 
} 

a klasa PayWayGatewayFactory:

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; 

      }; 
     } 
    } 
} 

Do tej pory jestem pod wrażeniem, to wszystko jest bardziej mniej w porządku (poprawcie mnie jeśli się 'Mylę). Udało mi się dostać do realizacji sposobu mojego CaptureOffsiteAction za:

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 
     ); 

    } 

pierwsze, pozwala zobaczyć, czy mam to prawo - raz rozpocząć proces przechwytywania (wykonać metodę) - wszystko działa zgodnie z oczekiwaniami, że skończę w Dolna część metody, tworzenie adresów URL sukcesu i niepowodzeń, przygotowywanie płatności poza siedzibą, hash i wszystko to i ostatecznie trafiają do bramki płatności za pośrednictwem HttpPostRedirect z prawidłowym identyfikatorem zamówienia, ceną itp. Ta część jest w porządku.

Po zapłaceniu, po powrocie do adresu URL sukcesu, ponownie trafiam do CaptureOffsiteAction :: wykonaj i sprawdź pgw_transaction_id - jeśli to ustawione, oznacza to, że wróciłem z płatności i powinienem wykryć albo płatne zlecenie, albo anulować/nieudana płatność.

Pytania są następujące:

  • w przypadku pomyślnego płatności - jak to zrobić 'Zamknij' kolejność

  • (konwersja koszyk na zamówienie, płatności jako znak niewoli, itp?) W innych bramkach płatności widzę, że istnieje wiele innych metod - powiedzmy, że są zainteresowane jedynie płatnością poza siedzibą sklepu za pośrednictwem przekierowania po wystąpieniu - co robi funkcja StatusAction? A kiedy to się nazywa?

tej pory znalazłem Payum (i PayumBundle) bardzo mylące, udało mi się wdrożyć 2 bramek poza biurem w ramach dnia wykorzystaniem OmniPay (na innych projektach, non-Sylius pokrewnych), ale nie wydaje się rozwiąż to zagadnienie Payuma. :(

Każda pomoc mile widziane, z góry dzięki

Odpowiedz

2

Przepraszamy za opóźnienie w odpowiedzi -. Udało mi się zorientować się, gdzie poszło źle

Cała idea polega na sekwencyjnym powołaniu Actions.W moim przypadku, że będzie:

  • CaptureOffsiteAction
  • StatusAction

Mój pierwszy błąd myślał że Payum używa tylko 1 akcję dla określonej pracy. Dokumentacja była trochę zagmatwana (a przynajmniej tak mi się wydawało), więc nie dostałem części, w której StatusAction rzeczywiście zajmuje się obsługą statusu zamówienia po powrocie z PG.

Więc z tego co zebrałem:

  • CaptureOffsiteAction obsługuje przekierowanie do bramki płatności, a czeki postback prośba o zwrot
  • Następnie StatusAction przejmuje, i sprawdza odpowiednich stanów zaznaczyć Zamówienie zrealizowane, Nowy lub Failed

Oto mój StatusAction wykonać metodę na przykład:

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(); 
} 

A oto końcowy CaptureOffsiteAction :: wykonać metoda:

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 
    ); 
} 

Nadzieja to pomaga niektórzy z was! Twoje zdrowie.

+0

Zajęło mi to 2 dni, aby to zrozumieć i poprawnie wdrożyć usługę Paybox. Dziękuję za twój komentarz. I nie zapomnij przyjąć odpowiedzi. – Aurel