Je dois intégrer une nouvelle passerelle de paiement à notre site Web d'entreprise, basé sur Social Engine. Il existe une extension pour ce CMS
appelée Advanced Payment Gateways qui permet l'intégration de nouvelles passerelles. En fait, il obtient le nom de votre passerelle et génère une structure squelette compressée sous forme de fichier afin que vous puissiez décompresser et télécharger sur votre serveur et ainsi fusionner avec le répertoire de l'application.
Je vais expliquer comment j'implémente ma passerelle sans Social Engine, et j'espère que quelqu'un pourra me dire comment je peux l'intégrer dans Social Engine.
Je me connecte d'abord à mon service PSP
:
$client = new nusoap_client('https://example.com/pgwchannel/services/pgw?wsdl');
Je prépare les paramètres suivants dans un tableau à envoyer à bpPayRequest
:
$parameters = array(
'terminalId' => $terminalId,
'userName' => $userName,
'userPassword' => $userPassword,
'orderId' => $orderId,
'amount' => $amount,
'localDate' => $localDate,
'localTime' => $localTime,
'additionalData' => $additionalData,
'callBackUrl' => $callBackUrl,
'payerId' => $payerId);
// Call the SOAP method
$result = $client->call('bpPayRequest', $parameters, $namespace);
Si la demande de paiement est acceptée, le résultat est une chaîne séparée par des virgules, le premier élément étant 0 .
Ensuite, nous pouvons envoyer le deuxième élément (référence id) à la passerelle de paiement comme suit via la méthode POST
:
echo "<script language='javascript' type='text/javascript'>postRefId('" . $res[1] . "');</script>";
<script language="javascript" type="text/javascript">
function postRefId (refIdValue) {
var form = document.createElement("form");
form.setAttribute("method", "POST");
form.setAttribute("action", "https://example.com/pgwchannel/startpay");
form.setAttribute("target", "_self");
var hiddenField = document.createElement("input");
hiddenField.setAttribute("name", "RefId");
hiddenField.setAttribute("value", refIdValue);
form.appendChild(hiddenField);
document.body.appendChild(form);
form.submit();
document.body.removeChild(form);
}
</script>
La passerelle renverra les paramètres suivants via la méthode POST
au rappel URL
que nous avons fourni dans la demande de paiement:RefId
(identifiant de référence tel que produit lors des étapes précédentes)ResCode
(Résultat du paiement: 0 dénote le succès)saleOrderId
(identifiant de commande transmis lors de la demande de paiement)SaleReferenceId
(le code de référence de vente est donné par PSP au commerçant)
Si ResCode
à l'étape précédente était 0 , alors nous aurions besoin de passer l'appel bpVerifyRequest
avec ce qui suit paramètres pour vérifier le paiement, sinon le paiement sera annulé.
$parameters = array(
'terminalId' => $terminalId,
'userName' => $userName,
'userPassword' => $userPassword,
'orderId' => $orderId,
'saleOrderId' => $verifySaleOrderId,
'saleReferenceId' => $verifySaleReferenceId);
// Call the SOAP method
$result = $client->call('bpVerifyRequest', $parameters, $namespace);
Dans le cas où le résultat de bpVerifyRequest
est nul, le paiement est certain et le commerçant doit fournir les biens ou services achetés. Cependant, il existe une méthode facultative bpSettleRequest
, qui est utilisée pour demander un règlement. Il est appelé comme suit:
$parameters = array(
'terminalId' => $terminalId,
'userName' => $userName,
'userPassword' => $userPassword,
'orderId' => $orderId,
'saleOrderId' => $settleSaleOrderId,
'saleReferenceId' => $settleSaleReferenceId);
// Call the SOAP method
$result = $client->call('bpSettleRequest', $parameters, $namespace);
Je suis confus en regardant les passerelles par défaut dans le plugin Payment Gateway, par exemple Paypal, Stripe, 2Checkout, etc. Comment puis-je intégrer cette logique de code dans le squelette de passerelle nouvellement créé? (la structure est illustrée ci-dessous):
Vous pouvez consulter le code source complet ici:
default.php
callback.php
J'ai résolu ce problème en ajoutant le code de paiement dans la classe Engine_Payment_Gateway_MyGateway
:
Une fois que l'utilisateur confirme sur la page SocialEngine qu'il souhaite payer, la méthode processTransaction()
à l'intérieur de la classe mentionnée est appelée et l'utilisateur est redirigé vers la page sécurisée de paiement du PSP. Une fois qu'ils ont terminé le paiement, c'est-à-dire payé avec succès ou échoué ou annulé la transaction, la page de PSP les redirige vers la page que nous lui avions envoyée plus tôt en tant que paramètre appelé callBackUrl. Là, vous recevrez des paramètres spécifiques à la PSP qui vous aideront à décider si le paiement a réussi et à demander à la PSP avec un autre SOAP appel pour confirmer le paiement et éventuellement lui demander de régler (déposer de l'argent) DÈS QUE POSSIBLE sur le compte du vendeur):
Ajouter à processTransaction ():
$data = array();
$rawData = $transaction->getRawData();
//Save order ID for later
$this->_orderId = $rawData['vendor_order_id'];
$this->_grandTotal = $rawData['AMT'];
$client = new nusoap_client('https://example.com/pgwchannel/services/pgw?wsdl');
$namespace = 'http://interfaces.core.sw.example.com/';
// Check for an error
$err = $client->getError();
if ($err) {
echo '<h2>Constructor error</h2><pre>' . $err . '</pre>';
die();
}
/* Set variables */
//Get price from SEAO
//$order_ids = Engine_Api::_()->getDbTable('orders','sitestoreproduct')->getOrderIds($this->parent_id);
//$price = Engine_Api::_()->getDbTable('orders','sitestoreproduct')->getGrandTotal($this->parent_id);
$terminalId = '1111111';
$userName = 'username';
$userPassword = '1111111';
$orderId = $rawData['vendor_order_id'];
$amount = $rawData['AMT'];
$localDate = date("Y") . date("m") . date("d");
$localTime = date("h") . date("i") . date("s");
$additionalData = $rawData['return_url'];
$callBackUrl = 'https://example.com/pgateway/pay/callback';
$payerId = '0';
/* Define parameters array */
$parameters = array(
'terminalId' => $terminalId,
'userName' => $userName,
'userPassword' => $userPassword,
'orderId' => $orderId,
'amount' => $amount,
'localDate' => $localDate,
'localTime' => $localTime,
'additionalData' => $additionalData,
'callBackUrl' => $callBackUrl,
'payerId' => $payerId
);
$result = $client->call('bpPayRequest', $parameters, $namespace);
if ($client->fault) {
echo '<h2>Fault</h2><pre>';
print_r($result);
echo '</pre>';
die();
} else { //Check for errors
$error = $client->getError();
if ($error) {
echo "An error occurred: ";
print_r($error);
die();
} else {
//break the code
$resultSegmts = explode(',', $result);
$ResCode = $resultSegmts [0];
if ($ResCode == "0") {
//Notify admin of the order
echo '<h3>Redirecting you to the payment page. Please wait...</h3><br/>';
echo '<script language="javascript" type="text/javascript">
postRefId("' . $resultSegmts[1] . '");
</script>';
} elseif ($ResCode == "25") {
echo "<h3>Purchase successful</h3>";
} else {
echo "<h3>PSP response is: $ResCode</h3>";
}
}
}
Ajouter à votre action callBack:
$this->view->message = 'This is callback action for PayController';
$RefId = $_POST['RefId'];
$ResCode = $_POST['ResCode'];
$saleOrderId = $_POST['SaleOrderId'];
$saleReferenceId = $_POST['SaleReferenceId'];
$this->_orderId = $saleOrderId;
$this->view->RefId = $RefId;
$this->view->saleOlderId = $saleOrderId;
$this->view->saleReferenceId = $saleReferenceId;
}
if ($ResCode == "0") {
try {
$client = new nusoap_client('https://example.com/pgwchannel/services/pgw?wsdl');
} catch (Exception $e) {
die($e->getMessage());
}
$namespace = 'http://interfaces.core.sw.example.com/';
$terminalId = "111111";
$userName = "username";
$userPassword = "11111111";
$parameters = array(
'terminalId' => $terminalId,
'userName' => $userName,
'userPassword' => $userPassword,
'orderId' => $saleOrderId,
'saleOrderId' => $saleOrderId,
'saleReferenceId' => $saleReferenceId
);
$resVerify = $client->call('bpVerifyRequest', $parameters, $namespace);
if ($resVerify->fault) { //Check for fault
echo "<h1>Fault: </h1>";
print_r($result);
die();
} else { //No fault: check for errors now
$err = $client->getError();
if ($err) {
echo "<h1>Error: " . $err . " </h1>";
} else {
if ($resVerify == "0") {//Check verification response: if 0, then purchase was successful.
echo "<div class='center content green'>Payment successful. Thank you for your order.</div>";
$this->view->message = $this->_translate('Thanks for your purchase.');
$this->dbSave(); //update database table
} else
echo "<script language='javascript' type='text/javascript'>alert( 'Verification Response: " . $resVerify . "');</script>";
}
}
//Note that we need to send bpSettleRequest to PSP service to request settlement once we have verified the payment
if ($resVerify == "0") {
// Update table, Save RefId
//Create parameters array for settle
$this->sendEmail();
$this->sendSms();
$resSettle = $client->call('bpSettleRequest', $parameters, $namespace);
//Check for fault
if ($resSettle->fault) {
echo "<h1>Fault: </h1><br/><pre>";
print_r($resSettle);
echo "</pre>";
die();
} else { //No fault in bpSettleRequest result
$err = $client->getError();
if ($err) {
echo "<h1>Error: </h1><pre>" . $err . "</pre>";
die();
} else {
if ($resSettle == "0" || $resSettle == "45") {//Settle request successful
// echo "<script language='javascript' type='text/javascript'>alert('Payment successful');</script>";
}
}
}
}
} else {
echo "<div class='center content error'>Payment failed. Please try again later.</div> ";
// log error in app
// Update table, log the error
// Show proper message to user
}
$returnUrl = 'https://example.com/stores/products'; //Go to store home for now. Later I'll set this to the last page
echo "<div class='center'>";
echo "<form action=$returnUrl method='POST'>";
echo "<input class='center' id='returnstore' type='submit' value='Return to store'/>";
echo "</form>";
echo "</div>";