支付接口介绍
我们的生活被框在了一个个熟悉的首屏icon里,独角兽和流量大户在行业赛道不断角逐,它们是这时代的主角
但还有这样一些,一直在坚持的个人开发者、个体户、个人创业者、小公司、小众产品,因为不够刚需、缺少推广、没有大腿可抱而不为人知,但产品足够用心、好玩好用、口碑扎实,这些给平淡生活带来一丝惊喜的人,正在通过自己独特的方式诠释、甚至影响着这个世界
我们坚信他们的价值,并愿意与其共同成长
每个梦想,都值得灌溉
EayPay 旨在解决需要使用交易数据流的个人、创业者、个体户等小微支付需求,帮助开发者使想法快速转变为原型
EayPay 只负责信息流,不接管资金流。资金无任何风险
官方网站:https://eaypay.com
本文阅读对象:商户系统(在线购物平台、人工收银系统、自动化智能收银系统或其他)集成EayPay涉及的技术架构师,研发工程师,测试工程师,系统运维工程师。
禁止接入的内容列表
平台已经和《中国互联网违法和不良信息举报中心》联通,报警信息会同时自动发送
以下业务,一经发现立即封禁,情节严重的直接报警至公安局
禁止接入的内容包括但不限于以下内容:
诈骗、BC严禁接入,发现此类立即上送至公安部网络安全保卫局
赛车、V盘、X资金盘、贷款、P2P、汇兑、ICO、二清支付、金融类严禁接入
1元购类、高额返利类 、多级分销类严禁接入
微信支付官方要求禁止接入的、所有国家法规规定禁止的
其它经工作人员鉴定不适合接入的
我们对违规行为零容忍。以上内容严禁接入,请勿挑战规则
协议规则
传输方式:HTTPS
字符编码:UTF-8
[API]Native 扫码支付(主扫)
扫码请求步骤:
- 构建请求参数
- POST 参数到请求地址
- 根据返回内容展示二维码
- 用户支付成功后接收异步通知
URL地址:https://eaypay.com/api/native
请求参数说明:
字段名称 | 字段类型 | 必填 | 说明 |
---|---|---|---|
mchid | string(16) | Y | 商户号 |
total_fee | int(11) | Y | 金额。单位:分 |
out_trade_no | string(32) | Y | 用户端自主生成的订单号 |
body | string(32) | N | 订单标题 |
attach | string(127) | N | 用户自定义数据,在notify的时候会原样返回 |
notify_url | string(255) | N | 接收微信支付异步通知的回调地址。必须为可直接访问的URL,不能带参数、session验证、csrf验证。留空则不通知 |
type | string(16) | N | 支付宝交易传值:alipay ,微信支付无需此字段 |
sign | int(32) | Y | 数据签名 详见签名算法 |
返回结果:
字段名称 | 字段类型 | 必填 | 说明 |
---|---|---|---|
return_code | int | Y | 1:请求成功 0:请求失败 |
return_msg | string(16) | Y | 返回消息 |
eaypay_order_id | string(32) | Y | EayPay 平台订单号 |
out_trade_no | string(32) | Y | 用户生成的订单号原样返回 |
total_fee | int(16) | N | 订单金额。单位:分 |
qrcode | string(128) | Y | 二维码图片地址 |
code_url | string(64) | Y | 可将该参数生成二维码展示出来进行扫码支付(有效期2小时) |
sign | int(64) | Y | 数据签名 详见签名算法 |
扫码支付PHP演示代码:
class Eaypay {
private $url = 'https://eaypay.com/api/native';
private $mchid = ''; // EayPay 商户号
private $key = ''; // 填写通信密钥
public function __construct($data=null) {
$this->data = $data;
}
public function pay(){
$data = $this->data;
$data['mchid'] = $this->mchid;
$data['sign'] = $this->sign($data);
return $this->post($data, $this->url);
}
public function post($data, $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
$rst = curl_exec($ch);
curl_close($ch);
return $rst;
}
public function sign(array $attributes) {
ksort($attributes);
$sign = strtoupper(md5(urldecode(http_build_query($attributes)) . '&key=' . $this->key));
return $sign;
}
}
$order = [
'body' => 'test', // 订单标题
'out_trade_no' => time(), // 订单号
'total_fee' => 120, // 金额,单位:分
];
$eaypay = new Eaypay($order);
$rst = $eaypay->pay();
print_r($rst);
[API]收银台支付接口
收银台方式同样是通过 JSAPI 方式发起的支付,只是简化了开发步骤和流程。适用于微信webview环境
扫码请求步骤:
- 构建请求参数
- 使用浏览器携带参数跳转至收银台地址
- 用户在收银台界面点击按钮发起支付
- 服务端接收异步通知
URL地址:https://eaypay.com/api/cashier
请求参数说明:
字段名称 | 字段类型 | 必填 | 说明 |
---|---|---|---|
mchid | string(16) | Y | 商户号 |
total_fee | int(11) | Y | 金额。单位:分 |
out_trade_no | string(32) | Y | 用户端自主生成的订单号 |
body | string(32) | N | 订单标题 |
attach | string(127) | N | 用户自定义数据,在notify的时候会原样返回 |
notify_url | string(255) | N | 接收微信支付异步通知的回调地址。必须为可直接访问的URL,不能带参数、session验证、csrf验证。留空则不通知 |
callback_url | string(128) | N | 用户支付成功后,前端跳转地址。留空则支付后关闭webview |
auto | int | N | auto=1:无需点击支付按钮,自动发起支付。默认手动点击发起支付 |
hide | int | N | hide=1:隐藏收银台背景界面。默认显示背景界面(这里hide为1时,自动忽略auto参数) |
logo | string(32) | N | 收银台显示的logo图片url |
sign | int(32) | Y | 数据签名 详见签名算法 |
请求返回:
收银台模式下,请求直接发起收银台支付。用户支付成功后,前台收银台页面自动关闭或跳转至自定义的 callback_url,后台系统会异步通知
特别提醒:支付后回调函数,并不能标示支付状态。用户需进一步完成验单逻辑
请求成功无返回。请求失败返回:
字段名称 | 字段类型 | 必填 | 说明 |
---|---|---|---|
return_code | int | Y | 0:请求失败 |
return_msg | string(32) | Y | 失败原因 |
sign | int(64) | Y | 数据签名 详见签名算法 |
收银台PHP演示代码:
$mchid = '**************'; // EayPay 商户号
$key = '**************'; // 填写通信密钥
// 构造订单参数
$order = [
'mchid' => $mchid,
'body' => '我是一个测试订单标题',
'total_fee' => 10,
'out_trade_no' => 'eaypay_jspay_demo_' . time(),
];
// 添加数据签名
$order['sign'] = sign($order, $key);
// 浏览器跳转到收银台
$url = 'https://eaypay.com/api/cashier?' . http_build_query($order);
header('Location: ' . $url);
// 签名函数
function sign($data, $key) {
array_filter($data);
ksort($data);
return strtoupper(md5(urldecode(http_build_query($data) . '&key=' . $key)));
}
[API]JSAPI 接口支付
JSAPI 接口使用前,请在后台设置支付目录
JSAPI 接口请求步骤:
- 参照《获取 OPENID》章节,获得 OPENID
- 通过该 api 构造订单参数获取 jsapi 支付参数
- 通过 jssdk 或 WeixinJsBridge 方式自行发起支付
- 服务端接收异步通知
URL地址:https://eaypay.com/api/jsapi
请求参数说明:
字段名称 | 字段类型 | 必填 | 说明 |
---|---|---|---|
mchid | string(16) | Y | 商户号 |
total_fee | int(11) | Y | 金额。单位:分 |
out_trade_no | string(32) | Y | 用户端自主生成的订单号 |
body | string(32) | N | 订单标题 |
attach | string(127) | N | 用户自定义数据,在notify的时候会原样返回 |
notify_url | string(255) | N | 接收微信支付异步通知的回调地址。必须为可直接访问的URL,不能带参数、session验证、csrf验证。留空则不通知 |
openid | string(32) | Y | 用户openid |
sign | int(32) | Y | 数据签名 详见签名算法 |
返回结果:
字段名称 | 字段类型 | 必填 | 说明 |
---|---|---|---|
return_code | int | Y | 1:请求成功 0:请求失败 |
return_msg | string(16) | Y | 返回消息 |
eaypay_order_id | string(32) | Y | EayPay 平台订单号 |
jsapi | string(255) | Y | 用于发起支付的支付参数 |
sign | int(64) | Y | 数据签名 详见签名算法 |
JSAPI请求PHP演示代码:
class Eaypay {
private $url = 'https://eaypay.com/api/jsapi';
private $mchid = ''; // EayPay 商户号
private $key = ''; // 填写通信密钥
public function __construct($data=null) {
$this->data = $data;
}
public function pay(){
$data = $this->data;
$data['mchid'] = $this->mchid;
$data['sign'] = $this->sign($data);
return $this->post($data, $this->url);
}
public function post($data, $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
$rst = curl_exec($ch);
curl_close($ch);
return $rst;
}
public function sign(array $attributes) {
ksort($attributes);
$sign = strtoupper(md5(urldecode(http_build_query($attributes)) . '&key=' . $this->key));
return $sign;
}
}
$order = [
'body' => 'test', // 订单标题
'out_trade_no' => time(), // 订单号
'total_fee' => 120, // 金额,单位:分
'openid' => 'xxxxxxxxxxx', // 通过openid接口获取到的openid
];
$eaypay = new Eaypay($order);
$rst = $eaypay->pay();
// 返回结果中包含`jsapi`字段,该字段的值即是前端发起时所需的6个支付参数
print_r($rst);
前端发起支付演示代码:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="format-detection" content="telephone=no">
<meta name="format-detection" content="email=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<link href="https://cdn.bootcss.com/weui/1.1.2/style/weui.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/zepto/1.2.0/zepto.min.js"></script>
</head>
<body style="padding:20px;">
<a href="javascript:;" class="weui-btn weui-btn_primary" id="payBtn">微信支付</a>
</body>
<script>
if (typeof WeixinJSBridge == "undefined") {
if (document.addEventListener) {
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
} else if (document.attachEvent) {
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
}
}
function onBridgeReady() {
WeixinJSBridge.call('hideOptionMenu');
}
$('#payBtn').on('click', function () {
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
// 以下6个支付参数通过eaypay的jsapi接口获取
// **************************
"appId": "wxc6215a653b0259ad",
"timeStamp": "15200000000",
"nonceStr": "3cJEu27X6KehHGM8",
"package": "prepay_id=wx163234040923141245861188",
"signType": "MD5",
"paySign": "D74EF3ADBCA224E435D321619710C065"
// **************************
},
function (res) {
if (res.err_msg == "get_brand_wcpay_request:ok") {
WeixinJSBridge.call('closeWindow');
}
}
);
});
</script>
[API]小程序支付
小程序发起支付的解决方案有两种,仅供测试使用
方案一:使用小程序消息,结合收银台模式,可以解决小程序支付
方案二:使用小程序跳转到 EayPay 小程序,支付后返回(下文详细介绍的方案)
一、后端按照下面参数构造订单参数:
字段名称 | 字段类型 | 必填参数 | 说明 |
---|---|---|---|
mchid | string(16) | Y | 商户号 |
total_fee | int(16) | Y | 金额。单位:分 |
out_trade_no | string(32) | Y | 用户端自主生成的订单号 |
body | string(32) | Y | 订单标题 |
attach | string(128) | Y | 用户自定义数据,在notify的时候会原样返回 |
notify_url | string(255) | Y | 异步通知地址 |
nonce | string(128) | Y | 随机字符串 |
sign | string(32) | Y | 数据签名 详见签名算法 |
二、小程序携带上述参数跳转到 EayPay 小程序
三、支付后自动返回,后端判断订单状态
代码参考:
// 本代码为演示碎片代码
// 需与文档中小程序章节结合使用 https://eaypay.com
// 跳转
// 为小程序的支付按钮绑定事件
bindPay: function() {
// 待传入的
wx.request({
url: '商户侧后端请求支付参数的网址',
success: response => {
let extraData = {
'mchid': response['mchid'], // 商户号
'total_fee': response['total_fee'],
'out_trade_no': response['out_trade_no'],
'body': response['body'],
'notify_url': response['notify_url'],
'attach': response['attach'],
'nonce': response['nonce'],
'sign': response['sign']
}
wx.navigateToMiniProgram({
appId: 'wx659c8c1fb2d877ac',
path: 'pages/pay',
extraData: extraData,
success: () => {
console.log('等待返回支付结果')
// 做已经点击过支付的标记
this.setData({
paying: true
})
},
fail: () => {
// 小程序跳转失败
// 做好错误处理
}
})
}
})
},
// 支付动作判断
// 在全局的 onShow 内,针对场景值为 1038、来源 appid 为 wx659c8c1fb2d877ac、跳转到的页面 id 为发起支付的页面,则标记为支付成功、记录支付的 eaypay_order_id
// app.js
App({
onShow: function (options) {
if (options.scene === 1038 && options.referrerInfo && options.referrerInfo.appId === 'wx659c8c1fb2d877ac') {
// 还应判断请求路径
let extraData = options.referrerInfo.extraData
this.globalData.paySuccess = extraData.success
this.globalData.resultCode = extraData.resultCode
this.globalData.msg = extraData.msg
this.globalData.eaypayOrderId = extraData.eaypayOrderId
}
},
globalData: {
resultCode: 'WAITING',
msg: '等待支付',
paySuccess: false,
}
})
// 在本页面的 onShow 内,如果已经点击过支付,则开始判断小程序是否返回成功,继而判断是否支付成功
onShow: function (options) {
console.log(options)
if (this.data.paying) { // 标记:已经点击过支付
// 注意轮询判断或延时判断支付
// 从跳转后状态取值
let eaypayOrderId = app.globalData.eaypayOrderId
// 注意请求后端判断是否支付成功而非通过前端判断
wx.request({
method: 'POST',
url: '后端检测是否支付成功的 url',
data: {
eaypayOrderId
},
success: response => {
if (response.data.paySuccess) {
// 后端返回支付成功
// 执行成功后逻辑
} else {
// 后端返回尚未支付
// 提醒用户重新支付或点击「我已支付」发起重检查
}
}
})
}
},
// 注意事项
// 页面内 onShow 检查小程序 app.js onShow 时建议使用轮询或延时,因为 app.js 的 onShow 和小程序页面的 onShow 均为异步,所以存在执行页面 onShow 时 app.js 的 onShow 还未执行的可能
// 请勿以小程序跳转结果作为判断订单状态的依据,须后端查询订单状态
[API]订单查询接口
用户发起支付后,可通过本接口发起订单查询来确认订单状态:
URL地址:https://eaypay.com/api/check
请求参数说明:
字段名称 | 字段类型 | 必填参数 | 说明 |
---|---|---|---|
mchid | string(32) | Y | EayPay 平台商户号 |
eaypay_order_id | string(32) | Y | EayPay 平台订单号 |
sign | int(32) | Y | 数据签名 详见签名算法 |
返回结果:
字段名称 | 字段类型 | 必填参数 | 说明 |
---|---|---|---|
return_code | int | Y | 1:请求成功 0:请求失败 |
mchid | string(32) | Y | EayPay 平台商户号 |
out_trade_no | string(32) | Y | 用户端订单号 |
eaypay_order_id | string(32) | Y | EayPay 平台订单号 |
transaction_id | string(32) | Y | 微信显示订单号 |
status | int | Y | 0:未支付,1:支付成功 |
openid | string(32) | N | 用户 OPENID |
total_fee | int(16) | N | 订单金额 |
paid_time | string(32) | N | 订单支付时间 |
attach | string(127) | N | 用户自定义数据 |
sign | int(32) | Y | 数据签名 详见签名算法 |
提示:请做好用户端订单号的唯一性处理。EayPay 在适当时机会开放通过自身订单号查询订单详情
此接口用户订单状态的辅助查询,请勿直接使用此接口做订单状态的高频轮询,调用频率过高可能会导致IP进入黑名单
正确的业务逻辑:商户侧服务器通过接收异步通知后更新自己订单状态,用户前端轮询应放在商户侧订单状态
特别提醒:一个支付成功的订单,如果接收到check查询,代表已经成功送达。此时如果异步通知正在执行,则会中断执行
PHP代码示例
class EayPay {
private $url = 'https://eaypay.com/api/check';
private $mchid = '123456789';// 填写EayPay商户号
private $key = 'f713986cfb69c263b909f09f774xxxxx';// 填写EayPay通信密钥
public function __construct($data=null) {
$this->data = $data;
}
public function check(){
$data = $this->data;
$data['mchid'] = $this->mchid;
$data['sign'] = $this->sign($data);
return $this->post($data, $this->url);
}
public function post($data, $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
$rst = curl_exec($ch);
curl_close($ch);
return $rst;
}
public function sign(array $attributes) {
ksort($attributes);
$sign = strtoupper(md5(urldecode(http_build_query($attributes)) . '&key=' . $this->key));
return $sign;
}
}
$post_data = [
'eaypay_order_id' => '2020041210225940886', //EayPay 平台订单号
];
$eaypay = new EayPay($post_data);
$rst = $eaypay->check();
print_r($rst);
//
//成功返回结果示范:{"return_code":"1","return_msg":"SUCCESS","out_trade_no":"2020041210365322749","eaypay_order_id":"2020041210225940886","transaction_id":"4200000523202004127340049109","status":1,"openid":"oRUTY5fwvC1XW6ekQLa_Q-4p1gao","paid_time":"2020-04-12 10:37:05","attach":"2031593","sign":"68F9ACF51EF16551A9EA5008540D9243"}
//失败返回结果师范:{"return_code":0,"return_msg":"订单不存在,您提交的订单号为:2020041210225940886","return_time":"2020-04-12 12:13:21"}
[API]关闭订单接口
该接口对未支付订单直接关闭,其他订单状态不做处理。如针对未支付或已订单关闭或退款可使用“撤销订单”接口;如只针对已支付订单全额退款可使用“退款”接口。
关闭订单接口只能针对30天以内的订单
关闭已经发起的订单,请求方式为POST
特别提示:订单发起后,并非一定要关闭
URL地址:https://eaypay.com/api/close
请求参数说明:
字段名称 | 字段类型 | 必填参数 | 说明 |
---|---|---|---|
mchid | string(32) | Y | EayPay 平台商户号 |
eaypay_order_id | string(32) | Y | EayPay 平台订单号 |
sign | int(32) | Y | 数据签名 详见签名算法 |
返回结果:
字段名称 | 字段类型 | 必填参数 | 说明 |
---|---|---|---|
return_code | int | Y | 1:请求成功 0:请求失败 |
return_msg | string(32) | Y | 返回消息 |
eaypay_order_id | string(32) | Y | EayPay 平台订单号 |
sign | int(32) | Y | 数据签名 详见签名算法 |
关闭订单接口PHP演示代码:
class Eaypay {
private $url = 'https://eaypay.com/api/close';
private $mchid = 'XXX';// 特写商户号
private $key = 'XXXXXXXXXXXXXXXXXX';// 填写通信密钥
public function __construct($eaypay_order_id=null) {
$this->eaypay_order_id = $eaypay_order_id;
}
public function refund(){
$data = array();
$data['eaypay_order_id'] = $this->eaypay_order_id;
$data['mchid'] = $this->mchid;
$data['sign'] = $this->sign($data);
return $this->post($data, $this->url);
}
public function post($data, $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
$rst = curl_exec($ch);
curl_close($ch);
return $rst;
}
public function sign(array $attributes) {
ksort($attributes);
$sign = strtoupper(md5(urldecode(http_build_query($attributes)) . '&key=' . $this->key));
return $sign;
}
}
$eaypay_order_id = 'XXXX'; // 订单号
$eaypay = new Eaypay($eaypay_order_id);
$rst = $eaypay->refund();
print_r($rst);
[API]撤销订单接口
该接口对未支付订单则直接关闭,对已支付订单则发起全额退款。如只针对未支付订单关闭可使用“关闭订单”接口;如只针对已支付订单全额退款可使用“退款”接口。
撤销订单主要是针对一些异常订单,例如无法查询或确定订单状态。
无论该订单是否被支付,发起撤销后,该订单如果被支付则自动原路退款,如果未支付则自动关闭订单
撤销订单接口只能应用于7天以内的订单
撤销已经发起的订单,请求方式为POST
URL地址:https://eaypay.com/api/reverse
请求参数说明:
字段名称 | 字段类型 | 必填参数 | 说明 |
---|---|---|---|
mchid | string(32) | Y | EayPay 平台商户号 |
eaypay_order_id | string(32) | Y | EayPay 平台订单号 |
sign | int(32) | Y | 数据签名 详见签名算法 |
返回结果:
字段名称 | 字段类型 | 必填参数 | 说明 |
---|---|---|---|
return_code | int | Y | 1:请求成功 0:请求失败 |
return_msg | string(32) | Y | 返回消息 |
eaypay_order_id | string(32) | Y | EayPay 平台订单号 |
sign | int(32) | Y | 数据签名 详见签名算法 |
撤销订单接口PHP演示代码:
class Eaypay {
private $url = 'https://eaypay.com/api/reverse';
private $mchid = 'XXX';// 特写商户号
private $key = 'XXXXXXXXXXXXXXXXXX';// 填写通信密钥
public function __construct($eaypay_order_id=null) {
$this->eaypay_order_id = $eaypay_order_id;
}
public function refund(){
$data = array();
$data['eaypay_order_id'] = $this->eaypay_order_id;
$data['mchid'] = $this->mchid;
$data['sign'] = $this->sign($data);
return $this->post($data, $this->url);
}
public function post($data, $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
$rst = curl_exec($ch);
curl_close($ch);
return $rst;
}
public function sign(array $attributes) {
ksort($attributes);
$sign = strtoupper(md5(urldecode(http_build_query($attributes)) . '&key=' . $this->key));
return $sign;
}
}
$eaypay_order_id = 'XXXX'; // 订单号
$eaypay = new Eaypay($eaypay_order_id);
$rst = $eaypay->refund();
print_r($rst);
[API]退款接口
该接口对已支付订单直接全额退款,其他订单状态不做处理。如针对未支付或已订单关闭或退款可使用“撤销订单”接口;如只针对未支付订单关闭可使用“关闭订单”接口。
对已经支付的订单发起退款,请求方式为POST
撤销已经发起的订单,请求方式为POST
URL地址:https://eaypay.com/api/refund
请求参数说明:
字段名称 | 字段类型 | 必填参数 | 说明 |
---|---|---|---|
mchid | string(32) | Y | EayPay 平台商户号 |
eaypay_order_id | string(32) | Y | EayPay 平台订单号 |
sign | int(32) | Y | 数据签名 详见签名算法 |
返回结果:
字段名称 | 字段类型 | 必填参数 | 说明 |
---|---|---|---|
return_code | int | Y | 1:请求成功 0:请求失败 |
return_msg | string(32) | Y | 返回消息 |
eaypay_order_id | string(32) | Y | EayPay 平台订单号 |
out_trade_no | string(32) | Y | 用户侧订单号 |
transaction_id | string(32) | Y | 微信支付订单号 |
total_fee | int(16) | Y | 订单金额 |
sign | int(32) | Y | 数据签名 详见签名算法 |
提示:成功退款的条件是,未结算款大于退款金额
退款接口PHP演示代码:
class Eaypay {
private $url = 'https://eaypay.com/api/refund';
private $mchid = 'XXX';// 特写商户号
private $key = 'XXXXXXXXXXXXXXX';// 填写通信密钥
public function __construct($eaypay_order_id=null) {
$this->eaypay_order_id = $eaypay_order_id;
}
public function refund(){
$data = array();
$data['eaypay_order_id'] = $this->eaypay_order_id;
$data['mchid'] = $this->mchid;
$data['sign'] = $this->sign($data);
return $this->post($data, $this->url);
}
public function post($data, $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
$rst = curl_exec($ch);
curl_close($ch);
return $rst;
}
public function sign(array $attributes) {
ksort($attributes);
$sign = strtoupper(md5(urldecode(http_build_query($attributes)) . '&key=' . $this->key));
return $sign;
}
}
$eaypay_order_id = 'XXXXXXXXXXXXX'; // 订单号
$eaypay = new Eaypay($eaypay_order_id);
$rst = $eaypay->refund();
print_r($rst);
[API]支付成功异步通知接口
用户支付成功后,平台会发送异步通知到订单携带的notify_url(如果有该参数的话),请求方式为 POST
请求参数说明:
字段名称 | 字段类型 | 必填参数 | 说明 |
---|---|---|---|
return_code | int | Y | 1:请求成功 0:请求失败 |
return_msg | string(32) | Y | 返回消息 |
eaypay_order_id | string(32) | Y | EayPay 平台订单号 |
out_trade_no | string(32) | Y | 用户侧订单号 |
total_fee | int(16) | Y | 金额。单位:分 |
time_end | string(32) | Y | 支付成功时间 |
openid | string(32) | Y | 用户OPENID标示,本参数没有实际意义,旨在方便用户端区分不同用户 |
body | string(127) | N | 用户自定义标题 |
attach | string(127) | N | 用户自定义数据 |
mchid | string(32) | Y | EAYPAY 商户号 |
type | string(32) | N | 支付类型。微信订单不返回该字段;支付宝订单返回:alipay |
sign | int(32) | Y | 数据签名 详见签名算法 |
提示:
- 接收通知的服务器请在3秒钟内响应(http状态码200则标记通知成功,其它状态码则标记通知失败,推送结束)
- 为保障推送到达率,系统可能多次进行通知推送,请做好去重逻辑
- 推送可能增加参数,请做好冗余处理,勿使用 hard code
- 商户系统对于支付结果通知的内容一定要验签,并校验返回的订单金额是否与商户侧的订单金额一致
- 知频率(秒):0,15,30,180,1800,3600。超过1小时后如需推送,可以在后台手动补发
- 异步通知过程中,如果该订单接收到check接口的成功查询,则异步通知在执行完当前任务后终止,不再继续通知
特别提醒:接收异步通知的服务器需在大陆境内备案服务器
接收回调流程示例:
$data = $_POST;
if($data['return_code'] == 1){
// 1.验签逻辑
// 2.验重逻辑
// 3.自身业务逻辑
// 4.返回 success 字符串(http状态码为200)
echo 'success';
}
[API]获取用户 OPENID
无需关注具体获取过程,系统自动处理
请求方式:浏览器跳转
请求参数说明:
字段名称 | 字段类型 | 必填参数 | 说明 |
---|---|---|---|
mchid | string(32) | Y | 商户号 |
callback_url | string(32) | Y | 接收 openid 的 url。必须为可直接访问的url,不能带session验证、csrf验证 |
sign | int(32) | Y | 数据签名 详见签名算法 |
注意:该接口不能在小程序中直接使用;不能在微信开发者工具里调试,需真机调试
提示:该openid具备唯一性,可做映射关系存储在本地数据库
请求示例:
假如需要接收 openid 的 url 是:
http://www.example.com/abc?uid=32
则直接通过浏览器跳转该 url 即可:
https://eaypay.com/api/openid?mchid=1234567890&callback_url=http://www.example.com/abc?uid=32
完成 openid 获取后,微信浏览器会自动跳转至:
http://www.example.com/abc?uid=32&openid=*************
[API]银行编码对应名称查询
根据银行简称查询银行详细名称。银行数据库会随时更新
URL地址:https://eaypay.com/api/bank
请求参数说明:
字段名称 | 字段类型 | 必填参数 | 说明 |
---|---|---|---|
mchid | string(32) | Y | 商户号 |
bank | string(32) | Y | 银行简写 |
sign | int(32) | Y | 数据签名 详见签名算法 |
返回结果:
字段名称 | 字段类型 | 必填参数 | 说明 |
---|---|---|---|
return_code | int | Y | 1:请求成功 0:请求失败 |
return_msg | string(32) | Y | 返回消息 |
bank | string(32) | Y | 银行名称 |
sign | int(32) | Y | 数据签名 详见签名算法 |
未查询到银行名称则返回 "not found"
PHP代码示例
class EayPay {
private $url = 'https://eaypay.com/api/bank';
private $mchid = '1234567890';// 填写EayPay商户号
private $key = 'f713986cfb69c263b909f09f774xxxxx';// 填写EayPay通信密钥
public function __construct($data=null) {
$this->data = $data;
}
public function bank(){
$data = $this->data;
$data['mchid'] = $this->mchid;
$data['sign'] = $this->sign($data);
return $this->post($data, $this->url);
}
public function post($data, $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
$rst = curl_exec($ch);
curl_close($ch);
return $rst;
}
public function sign(array $attributes) {
ksort($attributes);
$sign = strtoupper(md5(urldecode(http_build_query($attributes)) . '&key=' . $this->key));
return $sign;
}
}
$post_data = [
'bank' => 'CCB_DEBIT', //银行简写
];
$eaypay = new EayPay($post_data);
$rst = $eaypay->bank();
print_r($rst);
//成功返回结果示范:{"return_code":"1","return_msg":"SUCCESS","bank":"建设银行(借记卡)","sign":"B6F8DFAF782F3671D3C34D12955020E3"}
//失败返回结果师范:not found
[API]签名算法
EayPay 签名算法与微信官方签名算法一致
签名生成的通用步骤如下:
设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
在stringA最后拼接上&key=密钥得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值
特别注意以下重要规则:
参数名ASCII码从小到大排序(字典序);
如果参数的值为空不参与签名;
参数名区分大小写;
验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。
EayPay接口可能增加字段,验证签名时必须支持增加的扩展字段
举例:
例如传递的参数如下:
mchid: 12345
total_fee: 1
out_trade_no: 123123123123
第一步:对参数按照key=value的格式,并按照参数名ASCII字典序排序如下
mchid=12345&out_trade_no=123123123123&total_fee=1
第二步:对上一步中的字符串拼接&key=密钥
mchid=12345&out_trade_no=123123123123&total_fee=1&key=xxxxxxxxx
第三步:对上一步中字符串取MD5值
$sign = md5('mchid=12345&out_trade_no=123123123123&total_fee=1&key=xxxxxxxxx');
第四步:对上面md5值转化为大写
$sign = strtoupper($sign);
PHP代码示例
// 签名方法
function sign(array $data, $key) {
ksort($data);
$sign = strtoupper(md5(urldecode(http_build_query($data)).'&key='.$key));
return $sign;
}
// 用法示例
$data = [
'mchid' => '12345',
'total_fee' => 1,
'out_trade_no' => '123123123123',
];
// EayPay通信密钥
$key = 'xxxxxxxxxxx';
$sign = sign($data, $key);
SDK下载
PHP版本1:下载
PHP版本2:下载
Java版本:下载
小程序版本:下载
Note.js版本:下载
Python版本:下载
ASP版本:下载