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.