此方式與普通的托管集成方式付款的主要區別:
(1)請求的url不同
(2)提交form時,需要增加參數:payment_method (取值:card / echeck / paypal)
一、準備信息
1.merchantID:商家ID,商戶號,組織ID
2.Profile ID:Profile文件的ID
3.Profile Access Key:Profile 的訪問密鑰
4.Profile Secret Key:Profile的密鑰
5.url:
(1)沙盒(測試)環境url:
https://testsecureacceptance.cybersource.com/silent/embedded/pay
或者
https://testsecureacceptance.cybersource.com/silent/pay
(2)正式環境url:
https://secureacceptance.cybersource.com/silent/embedded/pay
?????? 或者
https://secureacceptance.cybersource.com/silent/pay
silent/embedded/pay:Iframe Transaction Endpoints (不跳轉到第三方頁面,成功/失敗,沒有取消)。
silent/pay:Process Transaction Endpoints(不跳轉到第三方頁面,成功/失敗,沒有取消)。
二、獲取需要提交給CyberSource的表單參數 --- 動態form所需要的參數
public function getCheckoutUrl()
{
? ??????// 卡信息
??????? $card_type =!empty($this->customParams['paymentParams']['card_type']) ?$this->customParams['paymentParams']['card_type'] : '';
??????? $card_number =!empty($this->customParams['paymentParams']['card_number']) ?$this->customParams['paymentParams']['card_number'] : '';
??????? $card_expiry_date =!empty($this->customParams['paymentParams']['card_expiry_date']) ?$this->customParams['paymentParams']['card_expiry_date'] : '';
??????? $card_cvn =!empty($this->customParams['paymentParams']['card_cvn']) ?$this->customParams['paymentParams']['card_cvn'] : '';
?????? //需要簽名的字段(用','隔開)
???????$signed_field_names = 'access_key,profile_id,transaction_uuid,signed_field_names,unsigned_field_names,'.
???????'signed_date_time,locale,transaction_type,reference_number,amount,'.
???????'currency,bill_to_forename,bill_to_surname,bill_to_address_line1,'.//bill_to_address_line2,'.
???????'bill_to_address_city,bill_to_address_country,bill_to_address_postal_code,bill_to_email,'.
???????'bill_to_phone,'.//ship_to_forename,ship_to_surname,ship_to_address_line1,ship_to_address_line2,'.
???????//'ship_to_address_city,ship_to_address_country,ship_to_address_state,ship_to_address_postal_code,ship_to_phone,'.
???????'override_custom_cancel_page,override_custom_receipt_page,'.
???????'card_type,card_number,card_expiry_date,card_cvn,payment_method';?? // payment_method:silent/pay,silent/embedded/pay追加字段
????????????? //第三方支付頁面的語言:en-us,zh-hk,zh-cn。英文,香港繁體中文,簡體中文
???????$locale = ‘’;
????????????? //簽名的時間,要用比北京時間小8小時的時間
???????$signed_date_time = gmdate("Y-m-d\TH:i:s\Z");
???????//$signed_date_time = date('Y-m-d') . 'T' . date('H:i:s') . 'Z';
???????//$signed_date_time = gmdate("Y-m-d\TH:i:s\Z", mktime() + 8 *3600);
???????//$signed_date_time = date("Y-m-d\TH:i:s\Z", time() - 8 *3600);
????????// 參數數組
???????$params = [
???????????'access_key' => ‘’,????????? // Profile的訪問密鑰,Profile Access Key
???????????'profile_id' => ‘’,??????????? //Profile文件的ID,Profile ID
???????????//唯一的商人生成的標識符。為每個事務包含access_key字段。此標識符對于每個事務都必須是唯一的。此字段用于檢查重復記錄索引嘗試。
???????????'transaction_uuid' => uniqid(),?//先使用 uniqid() 生成,進行請求;回調時,保存 返回值(交易ID)
???????????//由服務器簽名的以逗號分隔的響應數據列表。此列表中的所有字段都應該用于生成一個簽名,然后可以將其與要進行ve的響應簽名進行比較 釋放響應。
???????????'signed_field_names' => $signed_field_names,
???????????'unsigned_field_names' => '',
???????????//由服務器生成簽名的日期和時間。格式: yyyy-MM-DDThh: mm: ssZ例子22日Z等于2020年8月11日22:47:57(下午10:47:57)。
???????????// T的分離 具體的日期和時間。Z表示UTC。(小8小時)
???????????'signed_date_time' => $signed_date_time,
???????????//表示對于面向客戶的內容所要使用的語言。
???????????'locale' => $locale,
???????????//事務處理的類型。可能值:
???????????//??????????????? authorization
???????????//???????????????authorization,create_payment_token
???????????//???????????????authorization,update_payment_token
???????????//??????????????? sale
???????????//???????????????sale,create_payment_token
???????????//???????????????sale,update_payment_token
???????????//???????????????create_payment_token
???????????//???????????????update_payment_token
???????????//??????????????? 只有一個是 支持簽證點擊支付交易 的授權和銷售。
???????????'transaction_type' => 'authorization',? // sale
???????????//每個交易的唯一的商家生成的訂單參考或跟蹤編號。(自己平臺的訂單編號)
???????????'reference_number' => ‘’,
???????????//該訂單的總額。必須大于或等于零,并且必須等于包括稅額在內的每個行項目的總額。
???????????'amount' => ‘’,?????? //付款金額
? ??????????//貨幣類型(要注意類型!!!)
???????????'currency' => ‘USD’?????? //測試環境,用USD;正式環境,可以換成動態的貨幣類型,
???????????//客戶的名字。此名稱必須與板卡上的名稱相同。
???????????'bill_to_forename' => ‘’,
???????????//客戶姓氏。此名稱必須與板卡上的名稱相同。*
???????????'bill_to_surname' => ‘’,
? ??????????//賬單地址的第一行。*
???????????//在JCN網關上,當授權或銷售請求包括創建_支付_令牌或決策管理器時,則需要此字段。
???????????//這個字段是可選的,當重新選擇 在不創建支付憑證或決策經理的情況下請求授權或銷售。
???????????'bill_to_address_line1' => ‘’,
//??????????? 'bill_to_address_line2' => '',
???????????//賬單地址中的城市。*
???????????'bill_to_address_city' => ‘’,?
???????????//賬單地址的國家代碼 *(要用代碼!!!)
???????????'bill_to_address_country' => ‘’,
???????????//在賬單地址中的州或省。包含兩個字符的ISO州代碼和省代碼。這個字段將返回給美國和加拿大。
//??????????? 'bill_to_address_state' =>'address state',
???????????//帳單地址的郵政編碼。
???????????'bill_to_address_postal_code' => '',??? //默認可以用000000
???????????//客戶的電子郵件地址,包括完整的域名。*
???????????'bill_to_email' => ‘’,
???????????//客戶電話號碼。網絡源建議您,如果訂單來自美國以外的地區,則包括國家代碼。
???????????//請參見配置計費信息字段。此字段對于信用卡支付是可選的。
???????????//對于電子郵件檢查支付,如果需要此字段 你的處理器是網絡源ACH服務或遠程檢查
???????????'bill_to_phone' => ‘’,
???????????//客戶的公司名稱。(暫時不用)
???????????//'bill_to_company_name' => '',
???????????//客戶的名字。此名稱必須與板卡上的名稱相同。
//??????????? 'ship_to_forename' => ‘’,
???????????//客戶姓氏。此名稱必須與板卡上的名稱相同。
//??????????? 'ship_to_surname' => ‘’,
???????????//接收該產品的公司的名稱。(暫時不用)
???????????//'ship_to_company_name' => '',
???????????//第一行的航運地址。
//??????????? 'ship_to_address_line1' => '',????????? //默認可以用'default'
???????????//第二行航運地址。
//??????????? 'ship_to_address_line2' => '',????????? //默認可以用'default'
???????????//城市的運輸地址
//??????????? 'ship_to_address_city' => '',
???????????//運輸地址的國家代碼
//??????????? 'ship_to_address_country' => ‘’,
???????????//運輸地址的州或省。對于美國和加拿大,請使用標準的州、省和地區代碼。如果運輸地址是美國或加拿大,則需要此字段。
//??????????? 'ship_to_address_state' =>'default',
???????????//運輸地址的郵政編碼。如果賬單地址國家為美國或加拿大,則需要此字段。
//??????????? 'ship_to_address_postal_code' =>'default',?? //默認可以用000000
???????????//送貨地址的電話號碼。
//??????????? 'ship_to_phone' => ‘’,
???????????//運輸目的地。例如:商業、住宅、商店
???????????//'ship_to_type' => '',??????//留空/不傳/給個默認值
???????????//該產品的運輸方法。可能值:
???????????//? sameday:快遞或當日服務
???????????//? oneday:次日或通宵服務
???????????//? twoday:為期兩天的服務
???????????//? threeday:三天服務
???????????//? lowcost:最低成本服務
???????????//? pickup:商店皮卡
???????????//? other:其他運輸方式
???????????//? none:無運輸方式
???????????//'shipping_method' => '',???//留空/不傳/給個默認值
???????????//取消url(取消后,可以重新付款)
???????????'override_custom_cancel_page' => ‘’,
???????????//支付回調url(同步回調)
???????????'override_custom_receipt_page' => ‘’,
???????????//預授權(錢沒有真正到商家中,退款時,會靈活一些):0: Preauthorization
???????????//最終授權:1: Final authorization
//??????????? 'auth_indicator' => '1',
???????????// AUTOCAPTURE:自動捕獲,是不是不用再請求 rest api 的 /v1/payments/{id}/captures接口??????
???????????// STANDARDCAPTURE:標準捕獲
???????????// verbal:強制捕獲
//??????????? 'auth_type' => 'AUTOCAPTURE'
? ??????????// 卡信息
??????????? 'card_type' => $card_type,
??????????? 'card_number' => $card_number,
??????????? 'card_expiry_date' =>$card_expiry_date,
??????????? 'card_cvn' => $card_cvn,
??????????? // card, echeck, paypal
???????????'payment_method' => 'card',????// payment_method:silent/pay,silent/embedded/pay 追加字段
???????];
???????//參數簽名
???????$params['signature'] = $this->sign($params);
????????????? //保存請求的參數
????????????? ……
????????????? //返回form參數數組(k=v,kv形式)
???????????????return $params;
??? }
三、將返回的form參數數組,渲染到 隱藏的動態表單中,表單自動提交給CyberSource --- 動態form。也可以通過靜態form,填寫信息,然后手動點擊提交。
?????? //$p:返回的form參數數組
?????? //action中,填寫請求的CyberSource的url
????????public function buildOnlinePaymentSubmitForm($p) {
? ? ? ? ????????$params = $p;
? ? ? ????? ????$html = '<form id="cybersource-payment-form" action="url的地址(測試/正式)" method="post" style="display:none;">';
? ? ? ????? ????foreach ($params as $key => $value) {
? ? ? ? ? ? ????$html .= '<div class="form-group">
????????????????????????<label>' . $key . '</label>
????????????????????????<input class="form-control" type="text" name="' . $key . '" value="' . $value . '" />
????????????????????</div>
????????????????';
? ? ? ? ????????}
? ? ? ????????? $html .= '
????????????????????????<button type="submit">GO!</button>
????????????????????</form>
????????????????';
? ? ? ? ????????return $html;
? ? ????}
????????// 表單自動提交給CyberSource
????????$('#cybersource-payment-form')[0].submit();
四、第二步中,涉及到的簽名方法
?????? //根據 Profile Secret Key,對參數字符串進行簽名(加密)-托管集成方式
?????? //$params:form表單的參數(主要是提交給支付那邊的參數)
?????? function sign($params) {
???????????return $this->signData($this->buildDataToSign($params), 'Profile Secret Key的值');
??? ????}
?????? //根據 Profile Secret Key,對數據進行加密-托管集成方式
?????? //$data:form表單的參數(主要是提交給支付那邊的參數)
?????? //$profileSecretKey:profile secret key密鑰
?????? function signData($data, $profileSecretKey) {
???????????return base64_encode(hash_hmac(‘sha256’, $data, $profileSecretKey, true));
????????}
????// 構建需要加密的字符串-托管集成方式
????// $params:form表單的參數(主要是提交給支付那邊的參數)
????function buildDataToSign($params) {
??????? $signedFieldNames =explode(",", $params["signed_field_names"]);
??????? foreach ($signedFieldNames as $field) {
??????????? $dataToSign[] = $field ."=" . $params[$field];
??????? }
??? ????return$this->commaSeparate($dataToSign);
??? }
????// 用',',將kv數組,連接成字符串-托管集成方式
????// $dataToSign:k=v形式的字符串數組
????function commaSeparate($dataToSign) {
??????? return implode(",", $dataToSign);
??? }
五、第二步中,涉及到的 支付回調url(CyberSource回調請求,并傳遞參數)
?????? publicfunction verifyReturn()
??? {
???????//支付回調 請求的參數
???????$params = [];
???????foreach($_REQUEST as $name => $value) {
???????????$params[$name] = $value;
???????}
? ? ? ?$params['requestId'] = $_REQUEST['transaction_id'];
???????$responseBody = @json_encode($params);
???????//支付響應的決策類型:ACCEPT;DECLINE;REVIEW;ERROR;CANCEL
???????//$type = 'CYBERSOURCE_' . $params['decision'] . '_NOTIFY';
???????//記錄請求日志
????????????? ……
???????//驗證返回的 簽名 和 狀態碼
???????if (strcmp($params["signature"], $this->sign($params)) == 0 && $params['reason_code'] == '100') {
???????????//付款成功,處理邏輯
???????????????????? ……
???????????return true;
???????}
????????????? //付款失敗,處理邏輯
???????????return false;
??? }
六、第二步中,涉及到的 取消url
?????? 自定義方法,實現處理邏輯即可,一般是展示付款失敗的頁面。