Closed rescued898 closed 5 years ago
Merhaba,
Ödeme aracı kuruluşları ile daha önce hiç çalışma fırsatım olmadı. Lakin farklı platformlar için elimde ipara ve payu için örnek bir döküman var.
İPara İçin ;
<?php
class ipara3DModel {
private $card;
private $customer_ip;
private $amount;
private function createForm($bank) {
$public_key=$bank['ipara_public_key'];
$private_key=$bank['ipara_private_key'];
$success_url=$bank['success_url'];
$fail_url=$bank['fail_url'];
$order_id=$bank['order_id'];
$amount=$bank['total'];
//card
$this->card = array();
$this->card['owner_name'] = $bank['cc_owner'];
$this->card['number'] = $bank['cc_number'];
$this->card['expire_month'] = $bank['cc_expire_date_month'];
$this->card['expire_year'] = $bank['cc_expire_date_year'];
$this->card['cvc'] = $bank['cc_cvv2'];
$this->amount=$amount;
$this->customer_ip=$bank['customer_ip'];
//
if($bank['instalment']!=0){
$taksit=$bank['instalment'];
} else {
$taksit=1;
}
$action="https://www.ipara.com/3dgate";
$mode="P";
if ($bank['mode']=='test') {
$mode="T";
}
$timestamp = date("Y-m-d H:i:s");
$hash_text = $private_key . $order_id . number_format((float)$amount, 2, '', '') . $mode . $bank['cc_owner'] .
$bank['cc_number'] . $bank['cc_expire_date_month'] . $bank['cc_expire_date_year'] . $bank['cc_cvv2'] .
$bank['order_info']['firstname'] . $bank['order_info']['lastname'] . $bank['order_info']['email'] . $timestamp;
$token = $public_key . ":" . base64_encode(sha1($hash_text, true));
$inputs=array();
//test info pan: 4508034508034509 expire: 12/16 cv2:000 3dpass:a
$inputs=array('orderId'=>$order_id,
'amount'=>number_format((float)$amount, 2, '', ''),
'cardOwnerName'=>urlencode($bank['cc_owner']),
'cardNumber'=>$bank['cc_number'],
'cardExpireMonth'=>$bank['cc_expire_date_month'],
'cardExpireYear'=>$bank['cc_expire_date_year'],
'installment'=>$taksit,
'cardCvc'=>$bank['cc_cvv2'],
'mode'=>$mode,
'purchaserName'=>$bank['order_info']['firstname'],
'purchaserSurname'=>$bank['order_info']['lastname'],
'purchaserEmail'=>$bank['order_info']['email'],
'successUrl'=>$success_url,
'failureUrl'=>$fail_url,
'version'=>"1.0",
'transactionDate'=>$timestamp,
'token'=>$token
);
$form='<form id="webpos_form" name="webpos_form" method="post" action="'.$action.'">';
foreach($inputs as $key=>$value){
$form.='<input type="hidden" name="'.$key.'" value="'.$value.'" />';
}
$form.='</form>';
return $form;
}
public function methodResponse($bank){
date_default_timezone_set('Europe/Istanbul');
$response=array();
$response['form']=$this->createForm($bank);
//$response['redirect']=;
//$response['error']=;
return $response;
}
public function bankResponse($bank_response, $bank){
date_default_timezone_set('Europe/Istanbul');
$response=array();
$response['message']='';
// hash control
//TODO remove ->
$bank_response['result'] = $bank_response['result'];
$bank_response['order_id'] = $bank_response['orderId'];
$bank_response['amount'] = $bank_response['amount'];
$bank_response['mode'] = $bank_response['mode'];
// <- remove
$bank_response['public_key'] = isset($bank_response['publicKey'])?$bank_response['publicKey']:"";
$bank_response['echo'] = isset($bank_response['echo'])?$bank_response['echo']:"";
$bank_response['error_code'] = isset($bank_response['errorCode'])?$bank_response['errorCode']:"";
$bank_response['error_message'] = isset($bank_response['errorMessage'])?$bank_response['errorMessage']:"";
$bank_response['transaction_date'] = isset($bank_response['transactionDate'])?$bank_response['transactionDate']:"";
$bank_response['hash'] = isset($bank_response['hash'])?$bank_response['hash']:"";
$bank_response['three_d_secure_code'] = isset($bank_response['threeDSecureCode'])?$bank_response['threeDSecureCode']:"";
//$bank_response['amount'] = number_format((float)($bank_response['amount'] / 100), 2, '.', '');
if ($bank_response['hash'] != NULL) {
$hash_text = $bank_response['order_id'] . $bank_response['result'] . $bank_response['amount'] . $bank_response['mode'] . $bank_response['error_code'] . $bank_response['error_message'] . $bank_response['transaction_date'] . $bank_response['public_key'] . $bank['ipara_private_key'];
$hash = base64_encode(sha1($hash_text, true));
} else {
$response['message'].='Sayısal İmza tanımlı değil.<br/>';
$hash="nohash_error";
}
if ($hash != $bank_response['hash']) {
$response['message']="Ödeme cevabı hash doğrulaması hatalı. [result : " . $bank_response['result'] . ",error_code : " . $bank_response['error_code'] . ",error_message : " . $bank_response['error_message'] . "]";
$response['message'].=$hash.'<br/>';
$response['message'].=$bank_response['hash'].'<br/>';
$response['result']=0;
} else {
if ($bank_response['result'] == 1){
$response['message'].='3D Onayı Başarılı.<br/>';
//field
if($bank['instalment']!=0){
$taksit=$bank['instalment'];
} else {
$taksit=1;
}
$xml_fields=array('mode' => $bank_response['mode'],
'three_d_secure_code' => $bank_response['three_d_secure_code'],
'order_id' => $bank['order_info']['order_id'],
'amount' => $bank_response['amount'],
'three_d' => "true",
'installment'=>$taksit,
'client_ip'=>$this->customer_ip,
'public_key'=>$bank['ipara_public_key'],
'private_key'=>$bank['ipara_private_key']
);
$xml_fields['products']=$bank['products'];
$xml_fields['card']=array( 'owner_name'=> $this->card['owner_name'],
'number'=>$this->card['number'],
'expire_month'=>$this->card['expire_month'],
'expire_year'=>$this->card['expire_year'],
'cvc'=>$this->card['cvc']
);
$xml_fields['shipping_address']=array('name' => $bank['order_info']['shipping_firstname'],
'surname' => $bank['order_info']['shipping_lastname'],
'address' => $bank['order_info']['shipping_address_1'].$bank['order_info']['shipping_address_2'],
'zipcode' => $bank['order_info']['shipping_postcode'],
'city_text' => $bank['order_info']['shipping_city'].' '.$bank['order_info']['shipping_zone'],
'country_code' => $bank['order_info']['shipping_iso_code_2'],
'country_text' => $bank['order_info']['shipping_country'],
'phone_number' => $bank['order_info']['telephone']
);
$xml_fields['invoice_address']=array('name' => $bank['order_info']['payment_firstname'],
'surname' => $bank['order_info']['payment_lastname'],
'address' => $bank['order_info']['payment_address_1'].$bank['order_info']['payment_address_2'],
'zipcode' => $bank['order_info']['payment_postcode'],
'city_text' => $bank['order_info']['payment_city'].' '.$bank['order_info']['payment_zone'],
'country_code' => $bank['order_info']['payment_iso_code_2'],
'company_name' => $bank['order_info']['payment_company'],
'country_text' => $bank['order_info']['payment_country'],
'phone_number' => $bank['order_info']['telephone']
);
$xml_fields['purchaser']=array('name' => $bank['order_info']['firstname'],
'surname' => $bank['order_info']['lastname'],
'email' => $bank['order_info']['email'],
'gsm_number' => $bank['order_info']['telephone']
);
//field
$xml=$this->xmlSend($xml_fields);
$xml_response = new SimpleXMLElement($xml);
if ($xml_response != NULL) {
$iResult = $xml_response->result;
$iOrderid = $xml_response->orderId;
$iAmount = $xml_response->amount;
$iMode = $xml_response->mode;
$iPublicKey = $xml_response->publicKey;
$iErrorCode = $xml_response->errorCode;
$iErrorMessage = $xml_response->errorMessage;
$iTransactionDate = $xml_response->transactionDate;
$iHash = $xml_response->hash;
if ($iHash != NULL) {
$hash_text = $iOrderid . $iResult . $iAmount . $iMode . $iErrorCode . $iErrorMessage . $iTransactionDate . $iPublicKey . $bank['ipara_private_key'];
$hash = base64_encode(sha1($hash_text, true));
} else {
$response['message'].='Sayısal İmza tanımlı değil(API).<br/>';
$hash="nohash_error";
}
if ($hash != $iHash) {
$response['message']="Ödeme cevabı hash doğrulaması hatalı(API). [result : " . $bank_response['result'] . ",error_code : " . $bank_response['error_code'] . ",error_message : " . $bank_response['error_message'] . "]";
$response['result']=0;
} else {
if($iResult==1) {
$response['result']=1;
$response['message'].='Ödeme Başarılı<br/>';
$response['message'].='Result : '.$iResult.'<br/>';
$response['message'].='Amount : '.(number_format((float)($iAmount / 100), 2, '.', '')).'<br/>';
$response['message'].='Mode : '.$iMode.'<br/>';
$response['message'].='ErrorCode : '.$iErrorCode.'<br/>';
$response['message'].='ErrMsg : '.$iErrorMessage.'<br/>';
$response['message'].='TransDate : '.$iTransactionDate.'<br/>';
} else {
$response['result']=0;
$response['message'].='Ödeme Başarısız.<br/>';
$response['message'].='ErrorCode : '.$iErrorCode.'<br/>';
$response['message'].='ErrMsg : '.$iErrorMessage.'<br/>';
}
}
} else {
$response['result']=0;
$response['message'].='Ödeme cevabı xml formatında değil.<br/>';
}
} else {
$response['result']=0;
$response['message'].='3D doğrulama başarısız<br/>';
$response['message'].=$bank_response['error_message'];
}
}
//print_r($response);
return $response;
}
private function xmlSend($field){
//products
$xml_data_product_part="";
foreach($field['products']['products'] as $product) {
$xml_data_product_part .= "<product>\n" .
" <productCode>" . urlencode($product['model']) . "</productCode>\n" .
" <productName>" . urlencode($product['name']) . "</productName>\n" .
" <quantity>" . $product['quantity'] . "</quantity>\n" .
" <price>" . number_format((float)$product['price'], 2, '', '') . "</price>\n" .
"</product>\n";
}
//
date_default_timezone_set('Europe/Istanbul');
$request= "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" .
"<auth>\n" .
" <threeD>" . $field['three_d'] . "</threeD>\n" .
" <orderId>" . $field['order_id'] . "</orderId>\n" .
" <amount>" . $field['amount'] . "</amount>\n" .
" <cardOwnerName>" . urlencode($field['card']['owner_name']) . "</cardOwnerName>\n" .
" <cardNumber>" . $field['card']['number'] . "</cardNumber>\n" .
" <cardExpireMonth>" . $field['card']['expire_month'] . "</cardExpireMonth>\n" .
" <cardExpireYear>" . $field['card']['expire_year'] . "</cardExpireYear>\n" .
" <installment>" . $field['installment'] . "</installment>\n" .
" <cardCvc>" . $field['card']['cvc'] . "</cardCvc>\n" .
" <mode>" . $field['mode'] . "</mode>\n" .
" <threeDSecureCode>" . $field['three_d_secure_code'] . "</threeDSecureCode>\n".
" <products>\n" .
$xml_data_product_part .
" </products>\n" .
" <purchaser>\n" .
" <name>" . urlencode($field['purchaser']['name']) . "</name>\n" .
" <surname>" . urlencode($field['purchaser']['surname']) . "</surname>\n" .
" <email>" . $field['purchaser']['email'] . "</email>\n" .
" <gsmNumber>" . urlencode($field['purchaser']['gsm_number']) . "</gsmNumber>\n" .
" <clientIp>" . $field['client_ip'] . "</clientIp>\n" .
" <invoiceAddress>\n" .
" <name>" . urlencode($field['invoice_address']['name']) . "</name>\n" .
" <surname>" . urlencode($field['invoice_address']['surname']) . "</surname>\n" .
" <address>" . urlencode($field['invoice_address']['address']) . "</address>\n" .
" <zipcode>" . urlencode($field['invoice_address']['zipcode']) . "</zipcode>\n" .
" <city>" . urlencode($field['invoice_address']['city_text']) . "</city>\n" .
" <country>" . urlencode($field['invoice_address']['country_code']) . "</country>\n" .
" <companyName>" . urlencode($field['invoice_address']['company_name']) . "</companyName>\n" .
" <phoneNumber>" . urlencode($field['invoice_address']['phone_number']) . "</phoneNumber>\n" .
" </invoiceAddress>\n" .
" <shippingAddress>\n" .
" <name>" . urlencode($field['shipping_address']['name']) . "</name>\n" .
" <surname>" . urlencode($field['shipping_address']['surname']) . "</surname>\n" .
" <address>" . urlencode($field['shipping_address']['address']) . "</address>\n" .
" <zipcode>" . urlencode($field['shipping_address']['zipcode']) . "</zipcode>\n" .
" <city>" . urlencode($field['shipping_address']['city_text']) . "</city>\n" .
" <country>" . urlencode($field['shipping_address']['country_code']) . "</country>\n" .
" <phoneNumber>" . urlencode($field['shipping_address']['phone_number']) . "</phoneNumber>\n" .
" </shippingAddress>\n" .
" </purchaser>\n" .
"</auth>";
// URL below is payment gateway's adress ( API Server), it is NOT 3D Gateway.
$url = "https://api.ipara.com/rest/payment/auth";
$timestamp = date("Y-m-d H:i:s");
$token = "";
$hash_text = $field['private_key'] . $field['order_id'] . $field['amount'] . $field['mode'] . $field['three_d_secure_code'] . $timestamp;
$token = $field['public_key'] . ":" . base64_encode(sha1($hash_text, true));
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url); // set url to post to
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,0);
curl_setopt($ch, CURLOPT_SSLVERSION, 0);//prevent Poddle attack, have to set 0 to use TLS instead of SSL3
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/xml", "transactionDate: " . $timestamp, "version: 1.0", "token: " . $token));
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); // return into a variable
curl_setopt($ch, CURLOPT_TIMEOUT, 90); // times out after 90s
curl_setopt($ch, CURLOPT_POSTFIELDS, $request); // add POST fields
$result = curl_exec($ch);
if (curl_errno($ch)) {
$result='<Response><errorMessage>cUrl Error: '.curl_error($ch).'</errorMessage></Response>';
}
curl_close($ch);
return $result;
}
}
Payu İçin ;
<?php
class payuClassic {
public function methodResponse($bank){
$response=array();
$response['message']='';
$url = $bank['payu_alu_url'];
//$url = "https://secure.payu.com.tr/order/alu/v2";
$secretKey = $bank['payu_secret_key'];
if(($bank['cc_type']==1) || ($bank['cc_type']==2)){
$cardType="CCVISAMC";
} else if($bank['cc_type']==3){
$cardType="CCAMEX";
} else if($bank['cc_type']==4){
$cardType="CCDINERS";
} else if($bank['cc_type']==5){
$cardType="CCJB";
}
/*
CCVISAMC – Visa/MasterCard Kartı (varsayılan)
CCAMEX – AMEX Kartı
CCDINERS - Diners Club Kartı
CCJB – JCB Kart
*/
$product_name="";
$product_code="";
$product_info="";
foreach($bank['products']['products'] as $product) {
$product_name.=$product['model'].'(x'.$product['quantity'].').';
$product_code.=$product['model'].'x'.$product['quantity'];
$product_info.=$product['model'].', '.$product['quantity'].'pcs. '.$product['name'];
if(!empty($product['option'])) {
$option_info="";
foreach($product['option'] as $option){
$option_info.=','.$option['name'].':'.$option['value'];
}
$product_info.= $option_info;
}
$product_info.=PHP_EOL;
}
$arParams = array(
//The Merchant's ID
"MERCHANT" => $bank['payu_merchant_id'],
//order external reference number in Merchant's system
"ORDER_REF" => $bank['order_id'],
"ORDER_DATE" => gmdate('Y-m-d H:i:s'),
//First product details begin
"ORDER_PNAME[0]" => $product_name,
"ORDER_PCODE[0]" => $product_code,
"ORDER_PINFO[0]" => $product_info,
"ORDER_PRICE[0]" => $bank['total'],
"ORDER_QTY[0]" => "1",
//First product details end
"PRICES_CURRENCY" => $bank['order_info']['currency_code'],
"PAY_METHOD" => $cardType,//to remove
"CC_NUMBER" => $bank['cc_number'],
"EXP_MONTH" => $bank['cc_expire_date_month'],
"EXP_YEAR" => "20".$bank['cc_expire_date_year'],
"CC_CVV" => $bank['cc_cvv2'],
"CC_OWNER" => $bank['cc_owner'],
//Return URL on the Merchandt webshop side that will be used in case of 3DS enrolled cards authorizations.
"BACK_REF" => $bank['success_url'],
"CLIENT_IP" => $bank['customer_ip'],
"BILL_LNAME" => $bank['order_info']['firstname'],
"BILL_FNAME" => $bank['order_info']['lastname'],
"BILL_EMAIL" => $bank['order_info']['email'],
"BILL_PHONE" => $bank['order_info']['telephone'],
"BILL_COUNTRYCODE" => $bank['order_info']['payment_iso_code_2'],
//Delivery information
"DELIVERY_FNAME" => $bank['order_info']['shipping_firstname'],
"DELIVERY_LNAME" => $bank['order_info']['shipping_lastname'],
"DELIVERY_PHONE" => $bank['order_info']['telephone'],
"DELIVERY_ADDRESS" => $bank['order_info']['shipping_address_1'].$bank['order_info']['shipping_address_2'],
"DELIVERY_ZIPCODE" => $bank['order_info']['shipping_postcode'],
"DELIVERY_CITY" => $bank['order_info']['shipping_city'],
"DELIVERY_STATE" => $bank['order_info']['shipping_zone'],
"DELIVERY_COUNTRYCODE" => $bank['order_info']['shipping_iso_code_2']
);
if($bank['instalment']!=0){
$arParams["SELECTED_INSTALLMENTS_NUMBER"]=$bank['instalment'];
}
if ($bank['mode']!='live') {
$arParams["TESTORDER"]=1;
$arParams["PRICES_CURRENCY"]="TRY";
}
//begin HASH calculation
ksort($arParams);
$hashString = "";
foreach ($arParams as $key=>$val) {
$hashString .= strlen($val) . $val;
}
$arParams["ORDER_HASH"] = hash_hmac("md5", $hashString, $secretKey);
//end HASH calculation
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSLVERSION, 0);//prevent Poddle attack, have to set 0 to use TLS instead of SSL3
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($arParams));
$response_payu = curl_exec($ch);
$curlerrcode = curl_errno($ch);
$curlerr = curl_error($ch);
if (empty($curlerr) && empty($curlerrcode)) {
$parsedXML = @simplexml_load_string($response_payu);
if ($parsedXML !== FALSE) {
//Get PayU Transaction reference.
//Can be stored in your system DB, linked with your current order, for match order in case of 3DSecure enrolled cards
//Can be empty in case of invalid parameters errors
$payuTranReference = $parsedXML->REFNO;
if ($parsedXML->STATUS == "SUCCESS") {
//In case of 3DS enrolled cards, PayU will return the extra XML tag URL_3DS that contains a unique url for each
//transaction. For example https://secure.payu.com.tr/order/alu_return_3ds.php?request_id=2Xrl85eakbSBr3WtcbixYQ%3D%3D.
//The merchant must redirect the browser to this url to allow user to authenticate.
//After the authentification process ends the user will be redirected to BACK_REF url
//with payment result in a HTTP POST request - see 3ds return sample.
if (($parsedXML->RETURN_CODE == "3DS_ENROLLED") && (!empty($parsedXML->URL_3DS))) {
//header("Location:" . $parsedXML->URL_3DS);
//die();
$response['payu3d']=$parsedXML->URL_3DS;
} else {
$response['message'] = "SUCCESS [PayU reference number: " . $payuTranReference . "]";
$response['redirect'] = 'success';
}
} else {
$response['error'] = "FAILED: " . $parsedXML->RETURN_MESSAGE . " [" . $parsedXML->RETURN_CODE . "]";
if (!empty($payuTranReference)) {
//the transaction was register to PayU system, but some error occured during the bank authorization.
//See $parsedXML->RETURN_MESSAGE and $parsedXML->RETURN_CODE for details
$response['error'].= " [PayU reference number: " . $payuTranReference . "]";
}
}
}
} else {
//Was an error comunication between servers
$response['error']= "cURL error: " . $curlerr;
}
return $response;
}
public function bankResponse($bank_response,$bank){
$response=array();
$response['message']='';
if (!isset($bank_response['HASH']) || !empty($bank_response['HASH'])) {
//begin HASH verification
$arParams = $bank_response;
unset($arParams['HASH']);
$hashString = "";
foreach ($arParams as $val) {
$hashString .= strlen($val) . $val;
}
$secretKey = $bank['payu_secret_key'];
$expectedHash = hash_hmac("md5", $hashString, $secretKey);
if ($expectedHash != $bank_response["HASH"]) {
/*echo "FAILED. Hash mismatch";
die;*/
$response['result']=0;
$response['message']= "FAILED. Hash mismatch";
} else {
//end hash verification
//Use the information below to match against your database record.
$payuTranReference = $bank_response['REFNO'];
$amount = $bank_response['AMOUNT'];
$currency = $bank_response['CURRENCY'];
$installments_no = $bank_response['INSTALLMENTS_NO'];
if ($bank_response['STATUS'] == "SUCCESS") {
//Update status of the transaction in your database.
$response['result']=1;
$response['message']= "SUCCESS [PayU reference number: " . $payuTranReference . "]";
} else {
$response['result']=0;
$response['message']="FAILED ". $bank_response['RETURN_MESSAGE'] ."[". $bank_response['RETURN_CODE'] ."]";
$response['message'].= " [PayU reference number: " . $payuTranReference . "]";
}
}
} else {
$response['result']=0;
$response['message']="FAILED. Hash missing";
}
return $response;
}
}
Bu mantığa uygun şekilde ilgili firmalardan dökümanları isteyip uyarlamasını yapabilirsin diye düşünüyorum.
Moka, Paratika ve Paytr gibi ödeme aracı kuruluşları nasıl dahil ederiz bu projeye yardımlarınızı rica ederim