CyberSource支付二---托管集成方式付款(不跳转到第三方页面)

此方式与普通的托管集成方式付款的主要区别:

(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

       自定义方法,实现处理逻辑即可,一般是展示付款失败的页面。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容