I have a php code for a recurring payment to GP, but the payment gateway ends on error 31.
I was told by support that the signature is 2x base64 encoded and therefore you are getting a signature error.
In the code, focus on this line:
$params[‘regularSubscriptionPaymentRequest’][‘signature’] = new SoapVar($params[‘regularSubscriptionPaymentRequest’][‘signature’], XSD_BASE64BINARY);
Current code
<?php
$wsdl = __DIR__ . '/cws_v1.wsdl';
$privateKey = __DIR__ . '/private-key.pem';
$publicCert = __DIR__ . '/pub-key.pem';
$privateKeyPassword = '**************';
$soapLocation = 'https://test.3dsecure.gpwebpay.com/pay-ws/v1/PaymentService';
function signMessage($data, $privateKeyPath, $password)
{
$privateKey = openssl_pkey_get_private("file://{$privateKeyPath}", $password);
if (!$privateKey) {
throw new Exception('error private key');
}
if (!openssl_sign($data, $signature, $privateKey)) {
throw new Exception('error signature');
}
return base64_encode($signature);
}
function processRegularSubscriptionPayment($merchantNumber, $privateKeyPath, $password, $wsdl, $soapLocation)
{
try {
$streamContext = stream_context_create(array(
'http' => array(
'header' => 'Content-Type: application/soap+xml; charset=utf-8',
)
));
$client = new SoapClient($wsdl, array(
'trace' => 1,
'exceptions' => true,
'location' => $soapLocation,
'soap_version' => SOAP_1_1,
'encoding' => 'UTF-8',
'cache_wsdl' => WSDL_CACHE_NONE,
'stream_context' => $streamContext,
));
$messageId = date('YmdHis') . rand(1000, 9999);
$params = [
'regularSubscriptionPaymentRequest' => [
'messageId' => $messageId,
'provider' => 'XXXX',
'merchantNumber' => $merchantNumber,
'paymentNumber' => '123456789',
'masterPaymentNumber' => '123456788',
'orderNumber' => '123456789',
'captureFlag' => 1,
'cardHolderData' => [
'cardholderDetails' => [
'name' => 'Name Surname',
'email' => '[email protected]'
],
],
]
];
$name = htmlspecialchars($params['regularSubscriptionPaymentRequest']['cardHolderData']['cardholderDetails']['name'], ENT_QUOTES, 'UTF-8');
$email = htmlspecialchars($params['regularSubscriptionPaymentRequest']['cardHolderData']['cardholderDetails']['email'], ENT_QUOTES, 'UTF-8');
$params['regularSubscriptionPaymentRequest']['cardHolderData']['cardholderDetails']['name'] = $name;
$params['regularSubscriptionPaymentRequest']['cardHolderData']['cardholderDetails']['email'] = $email;
$dataToSign = $params['regularSubscriptionPaymentRequest']['messageId']
. "|" . $params['regularSubscriptionPaymentRequest']['provider']
. "|" . $params['regularSubscriptionPaymentRequest']['merchantNumber']
. "|" . $params['regularSubscriptionPaymentRequest']['paymentNumber']
. "|" . $params['regularSubscriptionPaymentRequest']['masterPaymentNumber']
. "|" . $params['regularSubscriptionPaymentRequest']['orderNumber']
. "|" . $params['regularSubscriptionPaymentRequest']['captureFlag']
. "|" . $params['regularSubscriptionPaymentRequest']['cardHolderData']['cardholderDetails']['name']
. "|" . $params['regularSubscriptionPaymentRequest']['cardHolderData']['cardholderDetails']['email'];
$params['regularSubscriptionPaymentRequest']['signature'] = signMessage($dataToSign, $privateKeyPath, $password);
$params['regularSubscriptionPaymentRequest']['signature'] = new SoapVar($params['regularSubscriptionPaymentRequest']['signature'], XSD_BASE64BINARY);
$response = $client->__soapCall('processRegularSubscriptionPayment', [$params]);
if (isset($response->resultCode) && $response->resultCode == '0') {
return $response->resultMessage;
} else {
return $response->resultCode . ' - ' . $response->resultMessage;
}
} catch (SoapFault $e) {
print_r($e);
return "SOAP error: " . $e->getMessage();
} catch (Exception $e) {
return "error: " . $e->getMessage();
}
}
$merchantNumber = '147258369';
echo processRegularSubscriptionPayment($merchantNumber, $privateKey, $privateKeyPassword, $wsdl, $soapLocation);