农业银行快捷支付php版说明和实例代码
- 接入的是shopnc,代码改改就可以用了,虽然不是一个完善的类,也可以按照类的方法直接调用,省得再去扣开发文档 农行在接收返回信息也会验证一次,还有一点就是页面通知返回结果
- 一定要用服务器通知,不然会出异常问题,导致问题
- 2016年5月12日11:15:41
大概有一下几个文件,
- <?php
- class abchina{
- //农行网关
- const GATEWAY = 'https://pay.abchina.com/ebus/trustpay/ReceiveMerchantTrxReqServlet';
- //标示
- private $code = 'abchina';
- /**
- * 支付接口配置信息
- *
- * @var array
- */
- private $payment;
- /**
- * 订单信息
- *
- * @var array
- */
- private $order;
- /**
- * 发送至农行的参数
- *
- * @var array
- */
- private $parameter;
- //发送请求
- private $request;
- //订单数据
- private $orderitems;
- private $payment_info;
- private $order_info;
- private $res;
- //签名算法
- const SIGNATURE_ALGORITHM = 'SHA1withRSA';
- //商户编号
- const MERCHANTID = '';
- //商户私钥加密密码
- const MERCHANTCERTPASSWORD = '';
- //网上支付平台证书
- const TRUSTPAYCERTFILE= './TrustPay.cer';
- //商户证书储存目录档名
- const MERCHANTCERTFILE= './fuwuqi.pfx';
- //报文里有的东西
- const TRX_TYPE_PAY_REQ = "PayReq";
- public function __construct($payment_info = array(),$order_info = array()) {
- $this->payment_info = $payment_info;
- $this->order_info = $order_info;
- }
- //提交订单
- public function submit() {
- // var_dump($this->payment_info);
- //
- // var_dump($this->order_info);
- // die;
- //没有自己传参的不要随意修改
- $this->order["PayTypeID"] = 'ImmediatePay'; //设定交易类型
- $this->order["OrderNo"] = $this->order_info['pay_sn']; //设定订单编号 自己传参数
- $this->order["OrderAmount"] = $this->order_info['api_pay_amount']; //设定交易金额 自己传参数
- // $this->order["OrderAmount"] = '0.01'; //设定交易金额 自己传参数 测试使用
- $this->order["CurrencyCode"] = 156; //设定交易币种
- $this->order["InstallmentMark"] = 0; //分期标识
- $this->order["OrderDate"] = date('Y/m/d'); //设定订单日期 (必要信息 - YYYY/MM/DD)
- $this->order["OrderTime"] = date('H:i:s'); //设定订单时间 (必要信息 - HH:MM:SS)
- $this->order["CommodityType"] = '0202'; //设置商品种类
- //2、订单明细
- $orderitem = array ();
- $orderitem["ProductName"] = "GG"; //商品名称 自己写随意
- $this->orderitems[0] = $orderitem;
- //3、生成支付请求对象
- $this->request["TrxType"] = self::TRX_TYPE_PAY_REQ; //设定交易类型
- $this->request["PaymentType"] = 'A'; //设定支付类型
- $this->request["PaymentLinkType"] = 1; //设定支付接入方式
- $this->request["NotifyType"] = 1; //设定通知方式
- $this->request["ResultNotifyURL"] = SHOP_SITE_URL."/api/payment/abchina/notify_url.php"; //设定通知URL地址 自己设定
- $this->request["IsBreakAccount"] = 0; //设定交易是否分账
- $aMerchantNo =1;
- //取得交易报文
- $tRequestMessage = $this->getRequestMessage();
- // echo '<pre>';
- // var_export($tRequestMessage);
- // echo '</pre>';
- // die;
- //组成完整交易报文
- $tRequestMessage = $this->composeRequestMessage($aMerchantNo,$tRequestMessage);
- // echo '<pre>';
- // var_export($tRequestMessage);
- // echo '</pre>';
- // die;
- //对交易报文进行签名
- $tRequestMessage = $this->signMessage($aMerchantNo, $tRequestMessage);
- // echo '<pre>';
- // var_export($tRequestMessage);
- // echo '</pre>';
- // die;
- //发送交易报文至网上支付平台
- $tResponseMessage = $this->sendMessage($aMerchantNo,$tRequestMessage);
- //验证网上支付平台响应报文的签名
- $this->res = $this->verifySign($tResponseMessage);
- // echo '<pre>';
- // var_export($tResponseMessage);
- // echo '</pre>';
- $PaymentURL = self::GetValue($tResponseMessage,'PaymentURL') ;
- $ReturnCode = self::GetValue($tResponseMessage,'ReturnCode') ;
- //验证报文签名正确而却返回码是0000,就可以跳转支付页面
- if($this->res == 1 && $ReturnCode=='0000' ){
- header("Location:".$PaymentURL);
- die;
- }else{
- header('<meta http-equiv="content-type" content="text/html;charset=utf-8">');
- die('abchina pay check error');
- }
- // var_dump($PaymentURL);
- //
- // var_dump($ReturnCode);
- // echo '<pre>';
- // var_export(json_decode($tResponseMessage,true));
- // echo '</pre>';
- // var_dump($res);
- // die;
- }
- public static function arrayRecursive(&$array, $function, $apply_to_keys_also = false){
- foreach ($array as $key => $value)
- {
- $array[$key] = $function($value);
- }
- }
- protected function getRequestMessage() {
- self :: arrayRecursive($this->order, "urlencode", false);
- self :: arrayRecursive($this->request, "urlencode", false);
- $js = '"Order":' . (json_encode(($this->order)));
- $js = substr($js, 0, -1);
- $js = $js . ',"OrderItems":[';
- $count = count($this->orderitems, COUNT_NORMAL);
- for ($i = 0; $i < $count; $i++) {
- self :: arrayRecursive($this->orderitems[$i], "urlencode", false);
- $js = $js . json_encode($this->orderitems[$i]);
- if ($i < $count -1) {
- $js = $js . ',';
- }
- }
- $js = $js . ']}}';
- $tMessage = json_encode($this->request);
- $tMessage = substr($tMessage, 0, -1);
- $tMessage = $tMessage . ',' . $js;
- $tMessage = urldecode($tMessage);
- return $tMessage;
- }
- private function composeRequestMessage($aMerchantNo,$aMessage) {
- $tMessage = "{\"Version\":\"V3.0.0\",\"Format\":\"JSON\",\"Merchant\":" . "{\"ECMerchantType\":\"" . "EBUS" . "\",\"MerchantID\":\"" . self::MERCHANTID . "\"}," . "\"TrxRequest\":" . $aMessage . "}";
- return $tMessage;
- }
- private function signMessage($aMerchantNo, $aMessage) {
- // public function signMessageOp() {
- //1、读取证书
- // $tTrustPayCertFile = dirname(__FILE__).'/TrustPay.cer';
- $tTrustPayCertFile = "fuwuqi.pfx";
- // $iTrustpayCertificate = openssl_x509_read(self :: der2pem(file_get_contents($tTrustPayCertFile)));
- // var_dump($tTrustPayCertFile);
- // var_dump(self::MERCHANTCERTPASSWORD);
- // die;
- openssl_pkcs12_read(file_get_contents($tTrustPayCertFile), $tCertificate, self::MERCHANTCERTPASSWORD);
- // var_dump($tCertificate);
- // die;
- //2、验证证书是否在有效期内
- $cer = openssl_x509_parse($tCertificate['cert']);
- // var_dump($cer);
- //3、取得密钥
- $pkey = openssl_pkey_get_private($tCertificate['pkey']);
- // var_dump($pkey);
- $key = $pkey;
- // $key = self :: $iMerchantKeys[$aMerchantNo -1];
- $signature = '';
- $data = strval($aMessage);
- if (!openssl_sign($data, $signature, $key, OPENSSL_ALGO_SHA1)) {
- return null;
- }
- $signature = base64_encode($signature);
- $tMessage = "{\"Message\":$data" . "," . '"Signature-Algorithm":' . '"' . self :: SIGNATURE_ALGORITHM . '","Signature":"' . $signature . '"}';
- return $tMessage;
- // return $pkey;
- // var_dump($iTrustpayCertificate);
- }
- private function sendMessage($aMerchantNo, $aMessage) {
- //组成<MSG>段
- $tMessage = strval($aMessage);
- $tURL = self::GATEWAY;
- $opts = array(
- 'http' => array(
- 'method' => 'POST',
- 'user_agent' => 'TrustPayClient V3.0.0',
- 'protocol_version' => 1.0,
- 'header' => array('Content-Type: text/html', 'Accept: */*'),
- 'content' => $tMessage
- ),
- 'ssl' => array(
- 'verify_peer' => false
- )
- );
- $context = stream_context_create($opts);
- $tResponseMessage = file_get_contents($tURL, false, $context);
- // $tTrxResponse = self::init($tResponseMessage);
- return $tResponseMessage;
- }
- private static function der2pem($der_data) {
- $pem = chunk_split(base64_encode($der_data), 64, "\n");
- $pem = "-----BEGIN CERTIFICATE-----\n" . $pem . "-----END CERTIFICATE-----\n";
- return $pem;
- }
- public static function verifySign($aMessage) {
- $TrustPayFile = "TrustPay.cer";
- $iTrustpayCertificate = openssl_x509_read(self :: der2pem(file_get_contents($TrustPayFile)));
- $tTrxResponse = self::GetValue($aMessage,'Message') ;
- $tSignBase64 = self::GetValue($aMessage,'Signature') ;
- $tSign = base64_decode($tSignBase64);
- $key = openssl_pkey_get_public($iTrustpayCertificate);
- $data = strval($tTrxResponse);
- return openssl_verify($data, $tSign, $key, OPENSSL_ALGO_SHA1);
- }
- public function GetValue($json,$aTag)
- {
- $json = $json;
- $index = 0;
- $length = 0;
- $index = strpos($json, $aTag, 0);
- if ($index === false)
- return "";
- do
- {
- if($json[$index-1] === "\"" && $json[$index+strlen($aTag)] === "\"")
- {
- break;
- }
- else
- {
- $index = strpos($json, $aTag, $index+1);
- if ($index === false)
- return "";
- }
- } while (true);
- $index = $index + strlen($aTag) + 2;
- $c = $json[$index];
- if ($c === '{')
- {
- $output = self::GetObjectValue($index, $json);
- }
- if ($c === '"')
- {
- $output = self::GetStringValue($index, $json);
- }
- return $output;
- }
- private function GetObjectValue($index, $json)
- {
- $count = 0;
- $_output = "";
- do
- {
- $c = $json[$index];
- if ($c === '{')
- {
- $count++;
- }
- if ($c === '}')
- $count--;
- if ($count !== 0)
- {
- $_output =$_output.$c;
- }
- else
- {
- $_output = $_output.$c;
- return $_output;
- }
- $index++;
- } while (true);
- }
- private function GetStringValue($index, $json)
- {
- $index++;
- $_output = "";
- do
- {
- $c = $json[$index++];
- if ($c !== '"')
- {
- $_output = $_output.$c;
- }
- else
- {
- return $_output;
- }
- } while (true);
- }
- /**
- * 返回地址验证(同步)
- *
- * @param
- * @return boolean
- */
- public function return_verify(){
- $this->order["PayTypeID"] = 'ImmediatePay'; //设定交易类型
- $this->order["OrderNo"] = $this->order_info['pay_sn']; //设定订单编号 自己传参数
- $this->order["OrderAmount"] = $this->order_info['api_pay_amount']; //设定交易金额 自己传参数
- // $this->order["OrderAmount"] = '0.01'; //设定交易金额 自己传参数 测试使用
- $this->order["CurrencyCode"] = 156; //设定交易币种
- $this->order["InstallmentMark"] = 0; //分期标识
- $this->order["OrderDate"] = date('Y/m/d'); //设定订单日期 (必要信息 - YYYY/MM/DD)
- $this->order["OrderTime"] = date('H:i:s'); //设定订单时间 (必要信息 - HH:MM:SS)
- $this->order["CommodityType"] = '0202'; //设置商品种类
- //2、订单明细
- $orderitem = array ();
- $orderitem["ProductName"] = "GG"; //商品名称 自己写随意
- $this->orderitems[0] = $orderitem;
- //3、生成支付请求对象
- $this->request["TrxType"] = self::TRX_TYPE_PAY_REQ; //设定交易类型
- $this->request["PaymentType"] = 'A'; //设定支付类型
- $this->request["PaymentLinkType"] = 1; //设定支付接入方式
- $this->request["NotifyType"] = 1; //设定通知方式
- $this->request["ResultNotifyURL"] = SHOP_SITE_URL."/api/payment/abchina/notify_url.php"; //设定通知URL地址 自己设定
- $this->request["IsBreakAccount"] = 0; //设定交易是否分账
- $aMerchantNo =1;
- //取得交易报文
- $tRequestMessage = $this->getRequestMessage();
- //组成完整交易报文
- $tRequestMessage = $this->composeRequestMessage($aMerchantNo,$tRequestMessage);
- //对交易报文进行签名
- $tRequestMessage = $this->signMessage($aMerchantNo, $tRequestMessage);
- //发送交易报文至网上支付平台
- $tResponseMessage = $this->sendMessage($aMerchantNo,$tRequestMessage);
- //验证网上支付平台响应报文的签名
- $this->res = $this->verifySign($tResponseMessage);
- $PaymentURL = self::GetValue($tResponseMessage,'PaymentURL') ;
- $ReturnCode = self::GetValue($tResponseMessage,'ReturnCode') ;
- //验证报文签名正确而却返回码是0000,就可以跳转支付页面
- if($this->res == 1){
- return true;
- }else{
- return false;
- }
- }
- public function getPayResult($param){
- return $this->res;
- }
- }
abchina.php
notify.php
- <?php
- error_reporting(7);
- function der2pem($der_data) {
- $pem = chunk_split(base64_encode($der_data), 64, "\n");
- $pem = "-----BEGIN CERTIFICATE-----\n" . $pem . "-----END CERTIFICATE-----\n";
- return $pem;
- }
- //$tt = json_decode(json_encode((array) simplexml_load_string(base64_decode($_POST['MSG']))), true);
- function verifySignXML($aMessage) {
- include dirname(__FILE__)."/XMLDocument.php";
- $TrustPayFile = dirname(__FILE__)."/TrustPay.cer";
- $iTrustpayCertificate = openssl_x509_read(der2pem(file_get_contents($TrustPayFile)));
- $aMessage = new XMLDocument($aMessage);
- $tTrxResponse = $aMessage->getValue('Message');
- $tSignBase64 = $aMessage->getValue('Signature');
- $tSign = base64_decode($tSignBase64);
- $key = openssl_pkey_get_public($iTrustpayCertificate);
- $data = strval($tTrxResponse);
- $result['res'] = openssl_verify($data, $tSign, $key, OPENSSL_ALGO_SHA1);
- $result['iRspRef'] =$aMessage->getValue('iRspRef'); //交易流水号
- $result['OrderNo'] =$aMessage->getValue('OrderNo'); //网站交易订单号
- $result['Amount'] =$aMessage->getValue('Amount'); //订单金额
- $result['VoucherNo'] =$aMessage->getValue('VoucherNo');
- return $result;
- }
- $rr = verifySignXML(base64_decode($_POST['MSG']));
- //var_dump($rr);
- //die;
- if ($rr['res'] == 1) {
- $_GET['act'] = 'payment';
- $_GET['op'] = 'return';
- $_GET['payment_code'] = 'abchina';
- $_GET['trade_no'] = $rr['iRspRef'];
- $_GET['out_trade_no'] = $rr['OrderNo'];
- $_GET['bank_total'] = $rr['Amount'];
- $_GET['extra_common_param'] = 'real_order';
- require_once(dirname(__FILE__).'/../../../index.php');
- } else {
- die('abchina notify check error');
- }
XMLDocument.php
- <?php
- class XMLDocument
- {
- private $iXMLString = '';
- public function getFirstTagName()
- {
- $tTagName = null;
- $tStartIndex = strpos($this->iXMLString, '<');
- $tEndIndex = strpos($this->iXMLString, '>');
- if ($tEndIndex > $tStartIndex)
- {
- $tTagName = substr($this->iXMLString, $tStartIndex + 1, $tEndIndex - ($tStartIndex + 1));
- }
- return $tTagName;
- }
- public function __construct($aXMLString='')
- {
- $this->init($aXMLString);
- }
- public function init($aXMLString)
- {
- $this->iXMLString = $aXMLString;
- return $this;
- }
- public function __toString()
- {
- return $this->iXMLString;
- }
- public function getValue($aTag)
- {
- $tXMLDocument = null;
- $tStartIndex = strpos($this->iXMLString, '<'.trim($aTag).'>');
- $tEndIndex = strpos($this->iXMLString, '</'.trim($aTag).'>');
- if (($tStartIndex !== FALSE) && ($tEndIndex !== FALSE) && ($tStartIndex < $tEndIndex))
- {
- $tXMLDocument = substr($this->iXMLString, $tStartIndex + strlen($aTag) + 2, $tEndIndex - ($tStartIndex + strlen($aTag) + 2));
- }
- return $tXMLDocument;
- }
- public function getValueNoNull($aTag)
- {
- $tValue = "";
- $tXML = $this->getValue($aTag);
- if ($tXML !== null)
- {
- $tValue = $tXML;
- }
- return $tValue;
- }
- public function getValueArray($aTag)
- {
- $tValues = array();
- $offset = 0;
- while(TRUE)
- {
- $tStartIndex = strpos($this->iXMLString, '<'.trim($aTag).'>', $offset);
- $tEndIndex = strpos($this->iXMLString, '</'.trim($aTag).'>', $offset);
- if (($tStartIndex === FALSE) || ($tEndIndex === FALSE) || ($tStartIndex > $tEndIndex))
- {
- break;
- }
- array_push($tValues, new XMLDocument(substr($this->iXMLString, $tStartIndex + strlen($aTag) + 2, $tEndIndex - ($tStartIndex + strlen($aTag) + 2))));
- $offset = $tEndIndex + 1;
- }
- return $tValues;
- }
- public function getValueArrayList($aTag)
- {
- return $this->getValueArray($aTag);
- }
- public function getDocuments($aTag)
- {
- return $this->getValueArray($aTag);
- }
- public function getFormatDocument($aSpace)
- {
- return $this->getFormatDocumentLevel(0, $aSpace);
- }
- private function getFormatDocumentLevel($aLevel, $aSpace)
- {
- $tSpace1 = str_repeat($aSpace, $aLevel + 1);
- $tTagName = $this->getFirstTagName();
- if ($tTagName === null)
- {
- return $this;
- }
- $tXMLString = "\n";
- $tXMLDocument = new XMLDocument($this->iXMLString);
- while (($tTagName = $tXMLDocument->getFirstTagName()) !== null)
- {
- $tTemp = $tXMLDocument->getValue($tTagName);
- $tSpace = "";
- if ($tTemp->getFirstTagName() !== null)
- {
- $tSpace = $tSpace1;
- }
- $tXMLString = "$tXMLString$tSpace1<$tTagName>".$tTemp->getFormatDocumentLevel($aLevel + 1, $aSpace)."$tSpace</$tTagName>\n";
- $tXMLDocument = $tXMLDocument->deleteFirstTagDocument();
- }
- return new XMLDocument($tXMLString);
- }
- public function deleteFirstTagDocument()
- {
- $tTagName = $this->getFirstTagName();
- $tStartIndex = strpos($this->iXMLString, "<$tTagName>");
- $tEndIndex = strpos($this->iXMLString, "</$tTagName>");
- if ($tEndIndex > $tStartIndex)
- {
- $this->iXMLString = substr($this->iXMLString, $tEndIndex + strlen($tTagName) + 3);
- if ($this->iXMLString === FALSE)
- {
- $this->iXMLString = "";
- }
- }
- return $this;
- }
- }
- ?>
代码包和开发文档说明下载地址 :http://download.csdn.net/detail/zh7314/9517627
便宜没好货你懂的,或者你可以直接复制代码也是可以使用的
农业银行快捷支付php版说明和实例代码的更多相关文章
- Android-支付宝快捷支付
支付宝的快捷支付Android版业务流程比較麻烦,出现的意外情况比較多.在此,简单说下开发流程以及出现错误的解决方式; 1.注冊支付业务.这里不在赘述.建立数据安全传输所须要的私钥公钥,这里採用的是R ...
- phonegap支付宝2.0移动快捷支付插件IOS版
坑爹的支付宝,一两年都没有更新sdk了,这两天突然更新sdk,而且更新的变化特别大,所以只能对之前的支付宝快捷支付插件重新写了一遍. 这样既顺应了支付宝的更新,同时也支持了ios8. 废话少说,集成过 ...
- 移动APP 支付宝快捷支付开发流程
[代码] [Java]代码 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ...
- 微信支付开发(1) JS API支付V3版(转)
http://www.cnblogs.com/txw1958/p/wxpayv3-jsapi.html 本文介绍微信支付下的jsapi实现流程 前言 微信支付现在分为v2版和v3版,2014年9月10 ...
- 微信支付java版V3验证数据合法性
[TOC] 1. 微信支付java版V3验证数据合法性 概要:使用微信支付接口时,微信会返回或回调给商户XML数据,开发者需要验证微信返回的数据是否合法. 特别提醒:商户系统对于支付结果通知的内容一定 ...
- 银联支付java版
注:本文来源于:< 银联支付java版 > 银联支付java版 2016年09月18日 15:55:20 阅读数:2431 首先去银联官网注册测试支付账户 下载对应的demo[ ...
- 「美团外卖APP签约快捷支付」流程体验
§1 添加银行卡 新用户在美团外卖APP订餐支付时,首先要绑定银行卡.如下是“添加银行卡”页,输入卡号后,系统自动调用卡bin库校验卡号的有效性,如果有效会显示发卡行和卡类型(借记卡/贷记卡). 这 ...
- java如何集成支付宝移动快捷支付功能
项目需要,需要在客户端集成支付宝接口.第一次集成,过程还是挺简单的,不过由于支付宝官方文档写的不够清晰,也是走了一些弯路,下面把过程写出来分享给大家.就研究了一下:因为使用支付宝接口,就需要到支付宝官 ...
- Android学习笔记_69_android 支付宝之网页支付和快捷支付
参考资料: https://b.alipay.com/order/productDetail.htm?productId=2013080604609654 https://b.alipay.com/o ...
随机推荐
- PHP 变量声明的意义
有人说,PHP是没有类型的语言,个人比较倾向于,PHP是弱类型的计算机脚本语言的说法. 计算机存储都是二进制的数据,要么是0,要么是1. 在抽象数据的过程中,是要有各种各样的标志位来识别数据. 虽然, ...
- Odd Even Linked List
Given a singly linked list, group all odd nodes together followed by the even nodes. Please note her ...
- java基本算法之快速排序
快速排序:是找出一个元素(理论上可以随便找一个)作为基准(pivot),然后对数组进行分区操作,使基准左边元素的值都不大于基准值,基准右边的元素值 都不小于基准值,如此作为基准的元素调整到排序后的正确 ...
- poj2492_A Bug's Life_并查集
A Bug's Life Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 34947 Accepted: 11459 D ...
- Spring 定时器Quartz的用法
Spring定时器Quartz的用法也很简单,需要引入quartz-all-1.5.2.jar java代码如下: package com.coalmine.desktop; import java. ...
- .deb包的安装方法
deb是Debian linux的安装格式,跟redhat的rpm非常相似,最基本的安装命令是: dpkg -i file.deb dpkg是Debian Package的简写,是为Debian专门开 ...
- Java基础之反射和动态代理
1,反射是依赖于Class对象,然后根据Class对象,去操作该类的资源的.Class对象是发射的基石! 问题1:人这类事物用什么表示?汽车这类事物用什么表示>计算机文件用什么表示?有如此多的事 ...
- nuget packages batch install
d:\nuget\nuget.exe install EnterpriseLibrary.Common -NoCache -Verbosity detailed -OutputDirectory D: ...
- Vitamio
前言 虽然Android已经内置了VideoView组件和MediaPlayer类来支持开发视频播放器,但支持格式.性能等各方面都十分有限,这里与大家一起利用免费的Vitamio来打造属于自己的And ...
- android tab选项卡的使用
项目做完了,写写博客,在项目中遇到的一些问题,或者是自己觉得很不错的东西.这一篇主要是想和大家分享一下我在项目中封装的一个东西,就是tab选项卡.先看看效果图: 我在网上看了很多有关选项卡的demo, ...