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.