程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> 使用php實現快錢支付功能

使用php實現快錢支付功能

編輯:關於PHP編程

    本項目用zend framework框架實現的
    modules/default/controllers/IndexController.php
    IndexController.php

    復制代碼 代碼如下:
    <?php
    class IndexController extends Zend_Controller_Action
    {
    public function init()
    {
    /* Initialize action controller here */
    }
    public function indexAction()
    {

    /*模擬訂單
    *$MockOrder是從數據庫取出來的信息,它包含一些塊錢Request的信息。這裡我寫死了。
    *orderId訂單號,數據庫表的主鍵(唯一)。 //必要字段
    *usr_idtype證件類型,根據自己需要。
    *usr_idcode證件號,根據自己需要。
    *etx_status是否優惠,根據自己需要。
    *time_create驗證是否符合優惠的時間,根據自己需要。
    *ets_license套餐代碼如同商品類別,根據自己需要。
    *contact_type聯系方式類型,固定選擇值1,2。1電子郵件,2手機號,根據自己需要,塊錢那邊可以為空。
    *contact_text聯系方式,根據contact_type來填寫,根據自己需要,塊錢那邊可以為空。
    *etsPrice套餐價格及商品價格,根據自己需要。
    *orderPrice實際價格,根據自己需要。
    *orderAmount訂單實際支付金額,這個要加手續費的。 //必要字段
    *orderTime訂單時間。 //必要字段
    *paySuccess訂單是否支付成功。 //必要字段
    *buySuccess賬號是否生成功,根據自己需要
    *payTime訂單支付成功時間。 //必要字段
    *總之凡是跟訂單有關的都是必要字段
    *orderId、orderAmount、orderTime為 Request所需字段
    *paySuccess、payTime為Response所需字段
    */
    $MockOrder = array();
    $MockOrder['orderId'] = '100000125';//訂單號。--必要
    $MockOrder['usr_idtype'] = '1';//證件類型,身份證
    $MockOrder['usr_idcode'] = '371111199011111111';//身份證號
    $MockOrder['etx_status'] = '0';//是否優惠,否
    $MockOrder['time_create'] = '1352338189';//驗證是否優惠時間
    $MockOrder['ets_license'] = '1';//套餐代碼及商品類別
    $MockOrder['contact_type'] = '1';//聯系方式類型 1,郵箱
    $MockOrder['contact_text'] = '[email protected]';//聯系方式,郵箱
    $MockOrder['etsPrice'] = '30800';//套餐價格及商品價格
    $MockOrder['orderPrice'] = '30800';//實際價格
    $MockOrder['orderAmount'] = '31100';//訂單實際支付價格,加手續費的。--必要
    $MockOrder['orderTime'] = '1352338199';//訂單生成時間。--必要
    $MockOrder['paySuccess'] = '0';//訂單是否支付成功。--必要
    $MockOrder['buySuccess'] = '0';//賬號是否生成成功
    $MockOrder['payTime'] = '0';//訂單支付時間。--必要

    //BillRequest就是快錢那邊需要的的一些參數
    $this->view->BillRequest = new Application_Model_BillRequest($MockOrder);
    Zend_Debug::dump($this->view->BillRequest);exit;
    }

    //bgUrl地址指向這裡
    public function receiveAction()
    {
    //receive數據庫設計
    /*用$MockReceive數組模擬
    * $MockReceive = array();
    * $MockReceive['id']主鍵;
    * $MockReceive['orderId']商戶訂單號;
    * $MockReceive['receiveTime']接受時間;
    * $MockReceive['queryString']http_build_encode($_REQUEST);
    * $MockReceive['dealId']快錢交易號;
    * $MockReceive['bankDealId']銀行交易號;
    * $MockReceive['payResult']處理結果10:支付成功;11:支付失敗;
    * $MockReceive['dealTime']快錢交易時間;
    * $MockReceive['payAmount']訂單實際支付金額;
    * $MockReceive['fee']費用;
    * $MockReceive['errCode']錯誤代碼;
    */


    /*$_REQUEST是快錢那邊返回來的數據
    * merchantAcctId人民幣賬號,與提交訂單時的塊錢賬號保持一致。
    * version網關版本,固定值:v2.0,與提交訂單時的網關版本號保持一致。
    * language網頁顯示語言種類,1中文顯示,與提交訂單時的網頁顯示語言種類保持一致
    * signType簽名類型,4PKI簽名,與提交訂單時的簽名類型保持一致
    * payType支付方式,00全部,與提交訂單時的支付方式保持一致
    * bankId銀行代碼
    * orderId商戶訂單號,與提交訂單時的商戶訂單號保持一致
    * orderTime商戶訂單提交時間,與提交訂單時的商戶訂單提交時間保持一致
    * orderAmount商戶訂單金額,與提交訂單時的商戶訂單金額保持一致。
    * dealId快錢交易號
    * bankDealId銀行交易號
    * dealTime快錢交易時間
    * payAmount訂單實際支付金額
    * fee費用
    * ext1擴展字段1,與提交訂單時的擴展字段1保持一致
    * ext2擴展字段2,與提交訂單時的擴展字段2保持一致
    * payResult處理結果 10:支付成功;11:支付失敗
    * errCode錯誤代碼,可為空
    * signMsg簽名字符串
    */
    $BillResponse = new Application_Model_BillResponse($_REQUEST);
    //$BillResponse->checkSignMsg驗證簽名字符串是否正確,防止bug漏洞等
    if($BillResponse->checkSignMsg){
    //判斷訂單支付是否成功
    if($BillResponse->isSuccess){
    //返回給快錢,快錢會按照redirecturl地址跳到新頁面,這裡是成功頁面
    return "<result>1</result><redirecturl>http://99bill/default/index/sucess</redirecturl>";exit;
    }else{
    //返回給快錢,快錢會按照redirecturl地址跳到新頁面,這個是失敗頁面
    return "<result>1</result><redirecturl>http://99bill/default/index/fail</redirecturl>";exit;
    }
    }
    //返回給快錢,快錢會按照redirecturl地址跳到新頁面,這個是失敗頁面
    return "<result>1</result><redirecturl>http://99bill/default/index/fail</redirecturl>";exit;
    }

    //redirecturl地址
    //成功
    public function success()
    {

    }

    //失敗
    public function fail()
    {

    }
    }


    modules/default/views/scripts/index/index.phtml
    https://www.99bill.com/gateway/recvMerchantInfoAction.htm

    復制代碼 代碼如下:
    <?php $BillRequest = (array)$this->BillRequest;?>
    <div style="display:none;">
    <form name="kqPay" action="https://www.99bill.com/gateway/recvMerchantInfoAction.htm" method="post">
    <?php foreach($BillRequest as $key => $val):?>
    <input type="hidden" name="<?php echo $key;?>" value="<?php echo $val;?>"/>
    <?php endforeach;?>
    <input type="submit" name="submit" value="提交到快錢" id="kqPay">
    </form>
    </div>
    <script>
    document.getElementById('kqPay').click();
    </script>


    models/BillRequest.php
    BillRequest.php

    復制代碼 代碼如下:
    <?php
    class Application_Model_BillRequest
    {
    public function __construct($MockOrder){
    /*
    * 人民幣網關賬號。
    *第一種方式:該賬號為11位人民幣網關商戶編號+01,該參數必填。01對應工商銀行。
    *第二種方式:該賬號為16位人民幣網關商戶
    */
    $this->merchantAcctId = "1001011111101";
    //服務器接收支付結果的後台地址,該參數務必填寫,絕對路徑//不能為空。
    $this->bgUrl = "http://99bill/default/index/receive";
    //商戶訂單號,以下采用時間來定義訂單號,商戶可以根據自己訂單號的定義規則來定義該值//不能為空。
    $this->orderId = 'TOLPC'.sprintf("%09d", $MockOrder['orderId']);
    //訂單金額,金額以“分”為單位,商戶測試以1分測試即可,切勿以大金額測試,該參數必填//不能為空
    $this->orderAmount =$MockOrder['orderAmount'];
    //訂單提交時間,格式:yyyyMMddHHmmss,如:20071117020101//不能為空。
    $this->orderTime = date("YmdHis", $MockOrder['orderTime']);
    //支付人姓名,可以為空。
    $this->payerName= "";
    //支付人聯系類型,1 代表電子郵件方式;2 代表手機聯系方式。可以為空。
    $this->payerContactType = "";
    //支付人聯系方式,與payerContactType設置對應,payerContactType為1,則填寫郵箱地址;payerContactType為2,則填寫手機號碼。可以為空。
    $this->payerContact = "";
    //商品名稱,可以為空。
    $this->productName= "TOLPC";
    //商品數量,可以為空。
    $this->productNum = "1";
    //商品代碼,可以為空。
    $this->productId = $MockOrder['ets_license'];
    //商品描述,可以為空。
    $this->productDesc = "";
    //支付方式,一般為00,代表所有的支付方式。如果是銀行直連商戶,該值為10,必填//不能為空
    $this->payType = "00";
    //編碼方式,1代表 UTF-8; 2 代表 GBK; 3代表 GB2312 默認為1,該參數必填//不能為空
    $this->inputCharset = "1";
    //網關版本,固定值:v2.0,該參數必填//不能為空
    $this->version = "v2.0";
    //語言種類,1代表中文顯示,2代表英文顯示。默認為1,該參數必填//不能為空
    $this->language = "1";
    //簽名類型,該值為4,代表PKI加密方式,該參數必填//不能為空
    $this->signType = "4";
    //接收支付結果的頁面地址,該參數一般置為空即可。
    $this->pageUrl = "";
    //擴展字段1,商戶可以傳遞自己需要的參數,支付完快錢會原值返回,可以為空。
    $this->ext1 = $MockOrder['orderId'];
    //擴展自段2,商戶可以傳遞自己需要的參數,支付完快錢會原值返回,可以為空。
    $this->ext2 = $MockOrder['orderTime'];
    //銀行代碼,如果payType為00,該值可以為空;如果payType為10,該值必須填寫,具體請參考銀行列表。
    $this->bankId = "";
    //同一訂單禁止重復提交標志,實物購物車填1,虛擬產品用0。1代表只能提交一次,0代表在支付不成功情況下可以再提交。可為空。
    $this->redoFlag = "";
    //快錢合作伙伴的帳戶號,即商戶編號,可為空。
    $this->pid = "";

    //快錢提供的request參數。
    $KeyOrders = array('inputCharset','pageUrl','bgUrl','version','language','signType','merchantAcctId','payerName','payerContactType','payerContact',
    'orderId','orderAmount','orderTime','productName','productNum','productId','productDesc','ext1','ext2','payType','bankId','redoFlag','pid',);

    //判斷快錢提供的request參數的值是否為空,把非空的參數及值重新組建數組
    foreach($KeyOrders as $key){
    if(''==$this->{$key}){continue;}
    $params[$key] = $this->{$key};
    }
    //http_build_query()生成URL-encode之後的請求字符串
    //urldecode()還原未編碼的字符串
    //getSignMsg() PKI加密,也可使用MD5加密
    //MD5加密方式 strtoupper(md5(urldecode(http_build_query($params))));這種不常用了。
    //常用PKI加密
    $this->signMsg = $this->getSignMsg(urldecode(http_build_query($params)));
    }

    //PKI加密技術

    public function getSignMsg($param){
    //99bill-rsa.pem是快錢的一個CA證書
    //本地隨機生成一個KEY,用此KEY加密數據 KEY為$priv_key_id
    $priv_key_id = openssl_get_privatekey(file_get_contents("99bill-rsa.pem", "r"));
    //用$priv_key_id給$param數據加密。
    //計算一個簽名字符串$param通過使用SHA1哈希加密,隨後$priv_key_id私鑰加密。數據本身是不加密的。
    openssl_sign($param, $signMsg, $priv_key_id, OPENSSL_ALGO_SHA1);
    //從存儲器上釋放$priv_key_id
    openssl_free_key($priv_key_id);
    //使用base64對數據進行編碼
    return base64_encode($signMsg);
    }
    }


    models/BillResponse.php
    BillResponse.php

    復制代碼 代碼如下:
    <?php
    class Application_Model_BillResponse
    {
    /*
    * __construct()構造函數
    * 生成19個參數及值,可能有一個參數的值為空,$this->errCode的值可能為空
    */
    public function __construct($response){
    $KeyOrders = array('merchantAcctId','version','language','signType','payType','bankId','orderId','orderTime','orderAmount',
    'dealId','bankDealId','dealTime','payAmount','fee','ext1','ext2','payResult','errCode', 'signMsg');
    foreach($KeyOrders as $key){
    $this->{$key} = $response[$key];
    }
    }
    /*
    * 檢查簽名字符串
    * 快錢返回的簽名字符串是$this->signMsg
    * 使用base64對前面字符串進行解碼
    * 驗證使用快錢給的公鑰驗證
    * 快錢那邊他們把返回來的參數值不為空的使用私鑰加密生成了$this->signMsg
    * 快錢給了我們私鑰對應的公鑰,我們使用這個公鑰來驗證。1成功,0失敗,-1錯誤。
    */
    public function checkSignMsg(){
    $KeyOrders = array('merchantAcctId','version','language','signType','payType','bankId','orderId','orderTime','orderAmount',
    'dealId','bankDealId','dealTime','payAmount','fee','ext1','ext2','payResult','errCode',);
    foreach($KeyOrders as $key){
    if(''==$this->{$key}){continue;}
    $params[$key] = $this->{$key};
    }
    //$pub_key_id 公鑰
    $pub_key_id = openssl_get_publickey(file_get_contents("99bill-rsa.cer", "r"));
    return openssl_verify(urldecode(http_build_query($params)), base64_decode($this->signMsg), $pub_key_id);
    }
    public function isSuccess(){
    //$this->payResult成功時10,失敗時11
    return '10'==$this->payResult;
    }
    public function getOrderId(){
    return str_replace('XXX', '', $this->orderId);
    }
    }


    需要一個公鑰和一個私鑰,這個不是一對的
    都是一半
    99bill-rsa.cer
    99bill-rsa.pem

    1. 上一頁:
    2. 下一頁:
    Copyright © 程式師世界 All Rights Reserved