GP webpay WS API SOAP - Jak na to v PHP?

Podstatná informace

GP webpay není konzistentní ve vrácení stavů prováděných plateb!

Pokud zákazník platbu dokončí, ale nevrátí se zpátky na eshop, tak Váš eshop nedostane informaci o tom, že bylo zaplaceno!

Tento postup považuji za nedůsledný; vyžadují milion podpisů, ale aby jejich server vždy zaslal primitivní informaci o změně stavu platby na návratovou URL, to už bylo moc práce.

Stav platby je z toho důvodu nutno kontrolovat periodicky pomocí druhé API přes SOAP, a tuto informaci mě potvrdili z podpory GP webpay.

Soubory

PHP ukázkový kód

<?php
/**
* GP webpay - WS API
* Druhá API pro zjištění stavu platby
*/
class GpWebPaySoap extends \SoapClient
{
   
/**
   * __construct
   *
   * @param (string) $providerId - ID poskytovatele - nejspíše potřebujete "0880"
       Příloha č. 5 – Identifikátory poskytovatelů platebních služeb
       0100 Cataps, s.r.o. (KB SmartPay)
       0110 Cataps, s.r.o. (KB SmartPay) / Worldline
       0300 Československá obchodní banka, a.s.
       0870 Global Payments s.r.o. – RO
       0880 Global Payments s.r.o. – CZ
       0902 Global Payments s.r.o. – SK
       0910 Global Payments s.r.o. – AT
       1111 UniCredit Bank Czech Republic and Slovakia, a.s. – SK
       2702 UniCredit Bank Czech Republic and Slovakia, a.s. - CZ
       5501 EVO Payments International s.r.o. (REVO)
       6500 Poštová banka, a.s.
       7500 Československá obchodná banka, a.s.
       8470 Global Payments Malta
       9203 Global Payments Europe, s.r.o. – CZ
       9348 Global Payments Europe, s.r.o. – HU
   * @param (string) $merchantNumber - ID obchodníka
   * @param (string) $privKeyPswd - heslo
   * @param (string) $privKeyFile - soubor privátní klíč
   * @param (string) $pubKeyFile - soubor veřejný klíč - tyhle blbosti jsou popsány v dokumentaci a generují se na portal.gpwebpay.com
   * @param (string) $isProduction = true - produkční rozhraní, jinak testovací
   */
   
function __construct($providerId, $merchantNumber, $privKeyPswd, $privKeyFile, $pubKeyFile, $isProduction = true)
   {
       if ($isProduction) {
           $endpoint =
'https://3dsecure.gpwebpay.com/pay-ws/v1/PaymentService';
       } else {
           $endpoint =
'https://test.3dsecure.gpwebpay.com/pay-ws/v1/PaymentService';
       }
       
       $this->providerId = $providerId;
       $this->merchantNumber = $merchantNumber;
       $this->privKeyPswd = $privKeyPswd;
       $this->privKeyFile = $privKeyFile;
       $this->pubKeyFile = $pubKeyFile;
       
       $wsdl = __DIR__.
'/schema/cws_v1.wsdl';
       
       parent::__construct($wsdl, [
           
'cache_wsdl' => WSDL_CACHE_NONE,
           
'trace' => 1,
           
'exceptions' => 1,
           
'location' => $endpoint
       ]);
   }
   
   
   
/**
   * Akce
   */
   
function call($action, $params)
   {
       $actionBase = preg_replace(
'~^get~', '', $action);
       $actionBase = strtolower(substr($actionBase, 0, 1)).substr($actionBase, 1);
       
       $params = array_merge([
           
'messageId' => uniqid('123456'),
           
'provider' => $this->providerId,
           
'merchantNumber' => $this->merchantNumber
       ], $params);
       
       $signData = implode(
'|', $params);
       
       
       $SIG = new CSignature($this->privKeyFile, $this->privKeyPswd, $this->pubKeyFile);
       $strSignature = $SIG->sign($signData);
       
       $params[
'signature'] = base64_decode($strSignature);
       
       
       
// voláme SOAP funkci
       
$res = parent::$action([ $actionBase.'Request' => $params ]);
       
       if (is_object($res)) {
           $res = $res->{$actionBase.
'Response'};
       } else {
           throw new Exception(
'GpWebPay: Invalid reponse: '.var_export($res, true));
       }
       
       
// pro úplnost zase ověřím podpis
       
$strSignature = base64_encode($res->signature);
       $res2 = get_object_vars($res);
       unset($res2[
'signature']);
       $signData = implode(
'|', $res2);
       
       if (!$SIG->verify($signData, $strSignature)) {
           throw new Exception(
'GpWebPay: Invalid response signature');
       }
       
       return $res;
   }
   
   
   
/**
   * Stav platby
   */
   
function getPaymentStatus($orderNumber)
   {
       return $this->call(
'getPaymentStatus', array('paymentNumber' => $orderNumber));
   }
   
   
// ... doplňte si další funkce
}



/**
* Tahle část kódu je uvedena v demo skriptech od GP webpay!
* Uvádím ji tady v nezměněné podobě
*/
class CSignature
{
   var $privateKey, $privateKeyPassword, $publicKey;
   
// parametry: jmeno souboru soukromeho klice, privateKeyPassword k soukromemu klici, jmeno souboru s publicKeym klicem
   // params: name of the private key, private key password, name of the public key
   // function CSignature($privateKey="./key/test_key.pem", $privateKeyPassword="111111", $publicKey="./key/gpe.signing_test.pem"){
   
function CSignature($privateKey, $privateKeyPassword, $publicKey)
   {
       $fp = fopen($privateKey,
"r");
       $this->privateKey = fread($fp, filesize($privateKey));
       fclose($fp);
       $this->privateKeyPassword=$privateKeyPassword;

       $fp = fopen($publicKey,
"r");
       $this->publicKey = fread($fp, filesize($publicKey));
       fclose($fp);
   }
   
   function sign($text)
   {
       $pkeyid = openssl_get_privatekey($this->privateKey, $this->privateKeyPassword);
       openssl_sign($text, $signature, $pkeyid);
       $signature = base64_encode($signature);
       openssl_free_key($pkeyid);
       return $signature;
   }

   function verify($text, $signature)
   {
       $pubkeyid = openssl_get_publickey($this->publicKey);
       $signature = base64_decode($signature);
       $result = openssl_verify($text, $signature, $pubkeyid);
       openssl_free_key($pubkeyid);
       return (($result==1) ? true : false);
   }
}

Informace aktuální k 01/2024 a jejich API jsou z roku 2015.