农业银行快捷支付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 ...
随机推荐
- eclipse for php现有项目不能导入问题
1.少了.project文件 解决办法:创建一个新项目,然后将新项目文件夹下的.project文件复制到将要导入的文件夹中.
- 【分享】SQL中的注入漏洞
例:假设一个账户密码的输入在数据库中是这样进行判断的. ' ) AS PWDCORRECT FROM T_USER WHERE FUSER= 'GUEST' 如果输入: ') AS PWDCORREC ...
- BZOJ 1060: [ZJOI2007]时态同步
Description 一个有根树,你只能进行增加操作,问你将所有叶节点到根的路径权值相同至少需要增加几次. Sol 我也不知道该叫什么算法... 反正就是记录一下到子节点到当前节点的最大距离统计答案 ...
- VS2013编译Qt5.6.0静态库
获取qt5.6.0源码包 直接去www.qt.io下载就好了,这里就不详细说了. 这里是我已经编译好的** 链接:http://pan.baidu.com/s/1pLb6wVT 密码: ak7y ** ...
- JQuery 菜鸟笔记(一)
什么是JQuery JQuery是一个优秀的javascript类库,jQuery以其简洁.快速等优点征服了众多javascript开发者.jQuery使用户能更方便地处理DOM.events.实现动 ...
- October 15th 2016 Week 42nd Saturday
Word to World. There are only two kinds of people who are really fascinating, people who know absolu ...
- 《BuildingMachineLearningSystemsWithPython》学习笔记
BuildingMachineLearningSystemsWithPython Python机器学习入门 数据分析五个步骤 读取和清洗数据 探索和理解输入数据[我的理解是业务理解] 分析如何将算法应 ...
- 8-06循环结构WHILE
WHILE 循环语句可以根据某些条件重复执行一条SQL语句或一个语句块. 语句: WHILE(条件) BEGIN 语句或语句块 END 程序调试: ALT+F5启动调试 F9切换断点 F10遂过程, ...
- UWP 图片剪切旋转工具
好久没撸随笔了,明天终于放假休息了..准备去进行信仰充值,看<魔兽>去(话说surface phone 好久出,让我这个做UWP的也充点信仰..) 先上下效果图: 在设计中,遇到一个问题, ...
- oracle的回收站介绍
昨天做的展示oracle表空间功能剩余空间的功能,发现查询表dba_free_space时特别慢,经网上搜索,说是由于表空间碎片和回收站(Oracle 10g以后才有)引起的,后来搜到一片介绍回收站的 ...