fix paybox

This commit is contained in:
Christophe LATOUR 2017-11-07 14:42:16 +01:00
parent 310bb5cbde
commit 069f7d2de3
2 changed files with 261 additions and 86 deletions

View File

@ -5,6 +5,7 @@ namespace App\Web\Controllers\Payments;
use App\Classes\CardDetector;
use Antadis\API\Front\Contracts\Controllers\PaymentController as PaymentContract;
use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\HttpException;
use ApiBaseController;
use ApiConfiguration;
@ -17,66 +18,108 @@ require_once _PS_MODULE_DIR_.'/paybox/paybox.php';
//TODO: Faire un client paybox
class PayboxController extends ApiBaseController {
//Authorization + débit
const ACTION_AUTH_AND_CAPTURE = '00003';
private $postFields = null;
//Inscription d'un nouvel abonné
const ACTION_CAPTURE_FROM_SUBSCRIBER = '00002';
//Débit
const ACTION_CAPTURE = '00002';
//Débit d'un abonné
const ACTION_CREATE_SUBSCRIBER = '0001';
//Authorization + Débit sur abonné
//http://www1.paybox.com/espace-integrateur-documentation/les-solutions-paybox-direct-et-paybox-direct-plus/les-operations-de-caisse-direct-plus/
const ACTION_CAPTURE_FROM_SUBSCRIBER = '000053';
private function getRefAbonne() {
return 'latour+bbb@antadis.com';
}
/**
* Returns payement data
*/
public function get(Request $request) {
$cart = $this->getCart();
return array(
'MONTANT' => strval(ApiTools::convertPrice($cart->getOrderTotal(), null, false) * 100),
'DEVISE' => '978',
'REFABONNE' => $this->getRefAbonne(),
'REFERENCE' => (int)$cart->id,
'DATEQ' => date('dmYHis'),
);
}
/**
* Returns num question for paybox
*/
public function getQuestion(Request $request) {
$numquestion = (int)ApiConfiguration::get('NUM_QUESTION_PAYBOX') + 1;
(int)ApiConfiguration::updateValue('NUM_QUESTION_PAYBOX', $numquestion);
return array(
'NUMQUESTION' => $numquestion,
);
}
/**
* {@inheritdoc}
*
* PAIEMENT NORMAL
*/
public function execPayment(Request $request, $type) {
public function validateOrder(Request $request, $type) {
$cart = $this->getCart();
if ($cart->OrderExists()) {
throw new \Exception('This cart has already been paid', 400);
//TODO: Trad
throw new HttpException(400, 'This cart has already been paid');
}
//CATCH EXCEPTION
$data = $this->validateInputData($request);
$this->validateResponse($request->user(), $request->input());
if ($type === 'normal') {
$response = $this->execRequest(self::ACTION_AUTH_AND_CAPTURE, $request->user(), $cart, $data);
} else {
//Création de l'abonné
$response = $this->execRequest(self::ACTION_CREATE_SUBSCRIBER, $request->user(), $cart, $data);
//CHECK INPUT DATA
$data = $request->input();
$actionType = $type === 'normal' ? self::ACTION_CAPTURE : self::ACTION_CAPTURE_FROM_SUBSCRIBER;
$response = $this->execRequest(self::ACTION_CAPTURE, $request->user(), $cart, $data);
//TODO: VAlidate RESPONSE
$response_data = $response['data'];
$data['NUMTRANS'] = $response_data['NUMTRANS'];
$data['NUMAPPEL'] = $response_data['NUMAPPEL'];
//Débit de l'abonnée précédemment créé
$response = $this->execRequest(self::ACTION_CAPTURE_FROM_SUBSCRIBER, $request->user(), $cart, $data);
}
return $this->validateResponse($request->user(), $response, $data, true);
return $this->validateResponse($request->user(), $response, $data, true, $type === 'normal' ? false : true);
}
//TODO: comment
protected function validateResponse(ApiUser $user, $response, $data, $create_order = false) {
protected function validateResponse(ApiUser $user, $response, $input_data = array(), $create_order = false, $save_card = false) {
$cart = $this->getCart();
$response_data = $response['data'];
$response_values = $response['values'];
if ($response_data === false) {
if ($response === false) {
return $this->server_error();
}
if (!isset($response_data['CODEREPONSE']) || $response_data['CODEREPONSE'] !== '00000') {
return $this->handleError($response_data);
if (!isset($response['CODEREPONSE']) || $response['CODEREPONSE'] !== '00000') {
return $this->handleError($response);
}
if ($create_order === true) {
//TODO
$response_values['u'] = $this->getCardName($data['card_number']);
$response_values['n'] = substr($data['card_number'], 0, 6);
$response_values['j'] = substr($data['card_number'], -2);
if ($create_order) {
$data = array(
'r' => (int)$cart->id,
'm' => $input_data['MONTANT'],
't' => (int)$response['NUMAPPEL'],
'p' => $response['AUTORISATION'],
//TODO
'c' => 'TODO',
'a' => 'CARTE',
's' => (int)$response['NUMTRANS'],
'e' => $response['CODEREPONSE'],
//TODO ?
'i' => '',
//TODO
'd' => substr($input_data['DATEVAL'], -2) . substr($input_data['DATEVAL'], 0, 2),
);
if ($save_card === true) {
$data['u'] = $input_data['PORTEUR'];
$data['n'] = $input_data['CARTE_FIRST'];
$data['j'] = $input_data['CARTE_LAST'];
$data['saved'] = true;
}
$paybox = new \Paybox();
$paybox->validateOrder((int)$cart->id, _PS_OS_PAYMENT_, $response_values['m'], $paybox->displayName, 'Success', array(), NULL, false, $user->secure_key, $response_values);
$paybox->saveInformationPaiement($response_values);
$info = '<b>Successful operation</b><br>'."\n\n";
$info .= 'PayBox version: '.$paybox->version."\n".'<br> POST '.print_r($this->postFields, true)."\n".'<br>GET '.print_r($response, true)."\n";
$paybox->validateOrder((int)$cart->id, _PS_OS_PAYMENT_, ((int)$input_data['MONTANT']) / 100, $paybox->displayName, $info, array(), NULL, false, $user->secure_key, $data);
$paybox->saveInformationPaiement($data);
}
return [];
}
@ -101,9 +144,7 @@ class PayboxController extends ApiBaseController {
* @return array
*/
protected function handleError($response) {
return $this->bad_request(array(
utf8_encode($response['COMMENTAIRE']),
));
throw new HttpException(400, utf8_encode($response['COMMENTAIRE']));
}
/**
@ -117,10 +158,6 @@ class PayboxController extends ApiBaseController {
* @return array $response The Request response data
*/
protected function execRequest($actionType, ApiUser $user, ApiCart $cart, $data) {
$card_number = $data['card_number'];
$date_validity = $data['date_validity'];
$cvv = $data['cvv'];
$curl = null;
if(ApiConfiguration::get('PBX_DEMO_MODE') == 0) {
$curl = curl_init('https://preprod-ppps.paybox.com/PPPS.php');
@ -131,69 +168,53 @@ class PayboxController extends ApiBaseController {
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_COOKIESESSION, true);
$question_number = (int)ApiConfiguration::get('NUM_QUESTION_PAYBOX') + 1;
(int)ApiConfiguration::updateValue('NUM_QUESTION_PAYBOX', $question_number);
$pbx_site = trim(ApiConfiguration::get('PBX_SITE'));
$pbx_rang = trim(ApiConfiguration::get('PBX_RANG'));
$pbx_id = trim(ApiConfiguration::get('PBX_ID'));
$montant = strval(ApiTools::convertPrice($cart->getOrderTotal(), null, false) * 100);
$montant = str_pad($montant, 10, '0', STR_PAD_LEFT);
$montant = isset($data['MONTANT']) ? $data['MONTANT'] : 0;
$num_question = isset($data['NUMQUESTION']) ? $data['NUMQUESTION'] : 0;
$num_trans = isset($data['NUMTRANS']) ? $data['NUMTRANS'] : 0;
$num_appel = isset($data['NUMAPPEL']) ? $data['NUMAPPEL'] : 0;
$dateq = isset($data['DATEQ']) ? $data['DATEQ'] : '';
$postfields = array(
'VERSION' => '00104',
'TYPE' => $actionType,
'TYPE' => '00002',
'SITE' => $pbx_site,
'RANG' => $pbx_rang,
'IDENTIFIANT' => $pbx_id,
'CLE' => 'EFNLJKFB',
'NUMQUESTION' => $question_number,
'MONTANT' => $montant,
'DEVISE' => '978',
'REFERENCE' => (int)$cart->id,
'REFABONNE' => $user->email,
'PORTEUR' => $card_number,
'DATEVAL' => $date_validity,
'CVV' => $cvv,
'NUMTRANS' => isset($data['NUMTRANS']) ? $data['NUMTRANS'] : null,
'NUMAPPEL' => isset($data['NUMAPPEL']) ? $data['NUMAPPEL'] : null,
'DATEQ' => date('dmYHis'),
'NUMQUESTION' => $num_question,
'MONTANT' => $montant,
'NUMTRANS' => $num_trans,
'NUMAPPEL' => $num_appel,
'DATEQ' => $dateq,
);
$this->postFields = $postfields;
if ($actionType === self::ACTION_CAPTURE_FROM_SUBSCRIBER) {
$postfields['PORTEUR'] = isset($data['PORTEUR']) ? $data['PORTEUR'] : '';
$postfields['DATEVAL'] = isset($data['DATEVAL']) ? $data['DATEVAL'] : '';
$postfields['CVV'] = isset($data['CVV']) ? $data['CVV'] : '';
$postfields['REFABONNE'] = isset($data['REFABONNE']) ? $data['REFABONNE'] : '';
}
$trame = http_build_query($postfields, '', '&');
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl,CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
curl_setopt($curl, CURLOPT_POSTFIELDS, $trame);
$response = curl_exec($curl);
curl_close($curl);
if ($response === false) {
$data = false;
} else {
$data = array();
parse_str($response, $data);
}
$values = array(
'm' => ((int) $montant) / 100,
'r' => (int) $cart->id,
't' => (int) isset($data['NUMAPPEL']) ? $data['NUMAPPEL'] : 0,
'p' => isset($data['AUTORISATION']) ? $data['AUTORISATION'] : '',
'c' => '',
'a' => 'CARTE',
's' => (int) isset($data['NUMTRANS']) ? $data['NUMTRANS'] : 0,
'e' => isset($data['CODEREPONSE']) ? $data['CODEREPONSE'] : '',
'd' => $date_validity,
'i' => isset($data['PAYS']) ? $data['PAYS'] : '',
'saved' => $actionType === self::ACTION_CREATE_SUBSCRIBER || self::ACTION_CAPTURE_FROM_SUBSCRIBER,
);
return array(
'data' => $data,
'values' => $values
);
$data = array();
parse_str($response, $data);
return $data;
}
/**
@ -225,4 +246,155 @@ class PayboxController extends ApiBaseController {
}
return $data;
}
/**
* Returns error based on code_response
*
* @param string $code_response
*
* @return string The error
* @copied from direct_paiement (module paybox
*/
public function getErrorMessage($code_reponse) {
switch ($code_reponse)
{
case '00001':
return 'Connection to the authorization center failed or an internal error occurred <br>'."\n";
break;
case '00003':
return 'Paybox error<br>'."\n";
break;
case '00004':
return 'Card number invalid or visual cryptogram invalid <br>'."\n";
break;
case '00006':
return 'Access refused or site/rank/identifier incorrect <br>'."\n";
break;
case '00008':
return 'Incorrect expiry date.<br>'."\n";
break;
case '00009':
return 'Error when during subscriber creation<br>'."\n";
break;
case '00010':
return 'Unknown currency<br>'."\n";
break;
case '00011':
return 'Amount incorrect<br>'."\n";
break;
case '00015':
return 'Payment already done<br>'."\n";
break;
case '00105':
return 'Error 00105<br>'."\n";
break;
case '00016':
return 'Subscriber already exists<br>'."\n";
break;
case '00021':
return 'Not authorized bin card<br>'."\n";
break;
case '00029':
return 'Not the same card used for the first payment.<br>'."\n";
break;
case '00030':
return 'Time-out > 15 mn before validation by the buyer when the buyer is on the page of payments of PAYBOX<br>'."\n";
break;
case '00031':
case '00032':
return 'Reserved<br>'."\n";
break;
case '00033':
return 'Unauthorized country code of the IP address of the cardholders browser<br>'."\n";
break;
case '00040':
return 'Operation without 3DSecure authentication, blocked by the fraud filter.<br>'."\n";
break;
case '99999':
return 'Payment waiting confirmation from the issuer<br>'."\n";
break;
case '00100':
return 'Transaction approved or successfully processed.<br>'."\n";
break;
case '00101':
case '00102':
return 'Contact the card issuer<br>'."\n";
break;
case '00103':
return 'Invalid retailer<br>'."\n";
break;
case '00104':
return 'Keep the card<br>'."\n";
break;
case '00105':
return 'Do not honor<br>'."\n";
break;
case '00107':
return 'Keep the card, special conditions<br>'."\n";
break;
case '00108':
return 'Approve after holder identification<br>'."\n";
break;
case '00112':
return 'Invalid transaction<br>'."\n";
break;
case '00113':
return 'Invalid amount<br>'."\n";
break;
case '00114':
return 'Invalid holder number<br>'."\n";
break;
case '00115':
return 'Card issuer unknown<br>'."\n";
break;
case '00117':
return 'Client cancellation<br>'."\n";
break;
case '00119':
return 'Repeat the transaction later<br>'."\n";
break;
case '00120':
return 'Error in reply (error in the servers domain).<br>'."\n";
break;
case '00124':
return 'File update not withstood<br>'."\n";
break;
case '00125':
return 'Impossible to situate the record in the file<br>'."\n";
break;
case '00126':
return 'Record duplicated, former record replaced<br>'."\n";
break;
case '00127':
return 'Error in edit in file update field<br>'."\n";
break;
case '00128':
return 'Access to file denied<br>'."\n";
break;
case '00129':
return 'File update impossible<br>'."\n";
break;
case '00130':
return 'Error in format<br>'."\n";
break;
case '00133':
return 'Expired card<br>'."\n";
break;
case '00138':
return 'Too many attempts at secret code.<br>'."\n";
break;
case '00151':
return 'provision insuffisante.<br>'."\n";
break;
case '00159':
return 'Suspicion of fraud.<br>'."\n";
break;
case '00000':
default:
return '<b>Successful operation</b><br>'."\n\n";
break;
}
}
}

View File

@ -96,8 +96,11 @@ $app->group(['middleware' => 'auth'], function() use ($app) {
|--------------------------------------------------------------------------
*/
$app->post('/payment/cheque', 'Payments\\ChequeController@execPayment');
$app->post('/payment/paybox/{type:normal|save_card}', 'Payments\\PayboxController@execPayment');
$app->post('/payment/paybox/card', 'Payments\\PayboxController@execPaymentWithSavedCard');
$app->get('/payment/paybox', 'Payments\\PayboxController@get');
$app->get('/payment/paybox/numquestion', 'Payments\\PayboxController@getQuestion');
$app->post('/payment/paybox/{type:normal|card}', 'Payments\\PayboxController@validateOrder');
// $app->post('/payment/paybox/{type:normal|save_card}', 'Payments\\PayboxController@execPayment');
// $app->post('/payment/paybox/card', 'Payments\\PayboxController@execPaymentWithSavedCard');
/*
|--------------------------------------------------------------------------