睿住社区支付
1 设计部分
1.1 服务商及普通商户支付
下图是表设计。
1.2 服务商及普通商户支付逻辑
当前设计兼容了两种支付场景:服务商及普通商户直连模式。
考虑到支付不依赖主数据,故门店信息与空间主数据解耦。支付能力不依赖空间主数据。
1.3 设计原型
2 车场微信支付
2.1 支付逻辑图
2.2 接口规范
概述:
当前仅对接微信公众号支付,其他支付入口视情况择期对接。
返回格式:
{
"code": "200",
"message":"提示",
"data": { 对象内容 }
}
返回码code: 取值说明
值 | 说明 |
---|---|
4031021 | token过期,凭证在2小时后失效 |
4031025 | token错误 |
4031026 | 无权限访问 |
9999 | 一般错误异常 |
2.3 全局字典
2.3.1 支付相关域名
支付服务只有一套环境-生产环境,当前仅有一个公众号。
环境 | 域名 | |
---|---|---|
SIT (测试) | https://iot.remacsmart.com | |
PROD(生产) | https://iot.remacsmart.com | |
2.3.2 支付配置相关域名
环境 | 域名 | |
---|---|---|
SIT (测试) | https://biz-admin-sit.smartmideazy.com | |
PROD(生产) | https://biz-admin.smartmideazy.com | |
2.3.3 中台业务数据字典
2.3.3.1 authen_type
Key | value | 说明 |
---|---|---|
authen_type | 微信公众号应用 | |
mini | 微信小程序应用 | |
app | 微信APP应用 | |
alipay_third | 支付宝第三方应用 | |
alipay_life | 支付宝生活号应用 | |
alipay_app | 支付宝APP应用 | |
alipay_mini | 支付宝APP小程序应用 | |
alipay_web | 支付宝网页应用 |
2.3.3.2 business_type
业务类型,对接的平台方。
Key | value | 说明 |
---|---|---|
business_type | community | 社区平台 |
2.3.3.2 pay_status
支付状态
Key | value | 说明 |
---|---|---|
pay_status | 1 | 待支付 |
2 | 已支付 | |
5 | 订单已关闭 | |
6 | 转入退款 | |
7 | 已取消 | |
8 | 支付失败 |
3 接口API
3.1 支付相关接口
注: 支付相关接口域名见《2.3.1 支付相关域名 》
APP支付宝授权获取code 参考: https://opendocs.alipay.com/open/218/wy75xo
3.1.2 获取token
注: 业务方发起付款前必须调用此接口。
同时支持微信和支付宝应用授权。
协议: https
URL: https://iot.remacsmart.com/wx/wechat/grant
method: post
body:
字段 | 类型 | 是否必传 | 说明 |
---|---|---|---|
code | String | 否 | 调用微信或支付宝应用授权后,返回的code,authen_type=wechat必传; 当 APP授权时,即authen_type=app及authen_type=alipay_app 不用传,由业务方调用中台此接口时需按内部服务鉴权,头部携带token及aeskey,具体方案见《https://confluence.mideazy.com/pages/viewpage.action?pageId=383877182》,验证通过后方可访问,否则中台将拒绝访问 。 |
space_id | String | 是 | 业务ID,由业务方定义。数据须同步到中台。在业务方必须唯一。 |
business_type | String | 否 | 业务平台标识,不传默认community 社区平台,其他平台必传,请按支付中台约定来传参。业务方需要保持 space_id+business_type唯一。 见《2.3.3 中台业务数据字典》 |
authen_type | String | 是 | 授权类型,见《2.3.3 中台业务数据字典》 |
member_id | String | 否 | 聚合支付必传。 |
third_part | String | 否 | 聚合支付必传。默认huifu |
返回结果:
{
"code": "200",
"message": "成功",
"data":
{"openid":"o6Cx46ISmbJ1oWL8-_KS7YWev7RQ","token":"eyJhbGciOiJIUzI1NiJ9.eyJrZXlfbWVtYmVyX2xvZ2luIjoie1widW5pb25pZFwiOlwib0VJd2U1NVBhYkp1XzlYMFRocElpS1ZIaTVrSVwiLFwib3BlbmlkXCI6XCJvNkN4NDZJU21iSjFvV0w4LV9LUzdZV2V2N1JRXCIsXCJuaWNrbmFtZVwiOlwi6bmP5ZOlXCIsXCJjaXR5XCI6XCJcIixcInByb3ZpbmNlXCI6XCJcIixcImNvdW50cnlcIjpcIlwiLFwiaGVhZGltZ3VybFwiOlwiaHR0cHM6Ly90aGlyZHd4LnFsb2dvLmNuL21tb3Blbi92aV8zMi9Ia1VpYmVjSG1qV0lwWXRHWkFxME0zVGJVRlhpYkxrVnlINkFHeGliUVQxNGtFNklJTTR3SDBpYzl3NTR6d3o2QTZEV29NMjFZWXBZaGVEcXdsa2J3WnlLd0EvMTMyXCIsXCJzZXhcIjowLFwibGFuZ3VhZ2VcIjpcIlwiLFwicHJpdmlsZWdlXCI6W10sXCJhdXRoZW5fdHlwZVwiOlwid2VjaGF0XCIsXCJidXNpbmVzc190eXBlXCI6XCJwYXJrcGF5XCIsXCJzcGFjZV9pZFwiOjEwMjAsXCJzcGFjZV9uYW1lXCI6XCLnvo7nmoTniankuJrmmbrmhaflgZzovablnLpcIixcImFwcElkXCI6XCJ3eGE5YzExOTMwZGUxY2U3MDZcIixcImFwcFNlY3JldFwiOlwiNTRhMzYxYjUyNjY0MjcyZDIzMmE3NTgyZGE3NDMyODRcIixcInNob3BpZFwiOjF9IiwiZXhwIjoxNjM4MjQzOTMyLCJpYXQiOjE2MzgyMzY3MzIsImp0aSI6IjA2MGUyZGVlLTdhOTQtNGYyNi05ZjA3LWM1MmMzZGViYmVmZiJ9.4J_5ES4sI6v5rf1fxlrPo_6X1c8x6d5ac58fGJcjdQ8
"
}
}
重要返回字段:
字段 | 类型 | 是否必返 | 说明 |
---|---|---|---|
openid | String | 否 | 调用授权后的用户标识(微信openid或支付宝user_id) |
token | String | 是 | 授权成功后,平台授予的token, 前端需要妥善保存,后续的请求中需要将其携带在http头部。用户的关键信息。 |
3.1.2 统一下单接口
同时支持微信和支付宝下单。
协议: https
URL: https://iot.remacsmart.com/wx/wechat/pay/unifyOrder
method: post
http头部: {"Authorization": $Token}, Token 为 《3.1.1 获取token 》接口返回的token值。
body:
字段 | 类型 | 是否必传 | 说明 |
---|---|---|---|
total_fee | String | 是 | 以分为单位,RMB分 |
quantity | String | 否 | 商品数量;小数。兼容更多后期业务场景。 |
item_price | String | 否 | 商品单价:保留两位小数。单位为RMB元;兼容更多后期业务场景。 |
business_order_id | String | 是 | 车场业务订单ID |
pay_callbak_url | String | 否 | 微信付款回调给业务发起方的URL,由业务方提供。 优先使用业务方提供的回调URL。若未提供,使用平台回调URL。 |
extra | JSONObject | 否 | 微信付款回调给业务发起方的URL的HTTP请求体,由业务方传参。 |
3.1.2.1 微信返回结果
公众号小程序返回:
{"code":"200","message":"统一下单成功", "data": {trade_type":"JSAPI","mch_id":"1609222413","sub_mch_id":"1616950579","appid":"wxa9c11930de1ce706","nonce_str":"iixmb071Of8gH5wz","device_info":"WEB","out_trade_no":"202111301100401383","total_fee":"1","sign":"0D1800FD3CE0101F9529B145E136D42D","result_code":"SUCCESS","return_code":"SUCCESS","return_msg":"OK","prepay_id":"wx30110041193633678cf1a7cb3989cf0000","timeStamp":"1638241241"} }
APP返回:
{"code":"200","message":"统一下单成功", "data":
{timeStamp:"1671631484", nonce_str:"5NSwhYcmlKhtKLjg", package:"Sign=WXPay",out_trade_no:"20221221220443DENJQD8OFB", device_info=WEB, total_fee=2, appid:"wx3576a38eb7f63e95", sign:"23381809F0E666C7C8EB779E22622E7D","partnerid":"1630001329", mch_id:"1630001329", rade_type:"APP", prepay_id:"wx21220444266681675b53ae131bb89c0000"}
重要返回字段:
字段 | 类型 | 是否必返 | 说明 |
---|---|---|---|
nonce_str | String | 是 | 生成签名的随机串 |
out_trade_no | String | 是 | 平台生成的唯一订单号 ,此订单号同步给微信 |
total_fee | String | 是 | 付款总额 |
prepay_id | String | 是 | 生成订单后获取预支付id |
timeStamp | String | 是 | 时间戳 |
sign | String | 是 | 微信返回签名 |
3.1.2.2 支付宝网站应用成功返回结果
{ code:"200", "message": "success", "out_trade_no":"XXXX", "body":"<form name=\"punchout_form\" method=\"post\" action=\"https://openapi.alipay.com/gateway.do?app_cert_sn=4d7a25e74fee81f597eebe1d181f426a&charset=UTF-8&alipay_root_cert_sn=687b59193f3f462dd5336e5abf83c5d8_02941eef3187dddf3d3b83462e1dfcf6&method=alipay.trade.wap.pay&sign=A0PM3KKhUDiIa9S65vesPz%2B5fVk1s%2FMbvN3VQCGLPL4tkDy4gsE1cLzo8qZuez6jsUCh8o%2BVAlT6QIoN6LBLBmrm727Lx9hMnPX0xb8zIHLi96GgFrBdzNaa36bp8mqc1ZGHL2pVKupQNEvFOxM6gTk8ZjkBNYGGnPFCJL8xv1C7ZISL5yUuUiQstxiF9opWs61nJzUlFcY8kFrRvE2owA6MDklB9PO65oEK%2BgCTbRHPwz%2Ff5RIb8NpFR2%2FVwlAPOIaVwBtg94q2u8gymX%2Bn81cEQ8nw69BeJu%2F9BlC0a4ewda%2Bc46hbuOc4NCJkGAvZEkMkfgZDHHnpfm3PKx4Dqg%3D%3D&return_url=https%3A%2F%2Fiot.remacsmart.com%2Fwx%2Falipay%2Fgate%2FreturnUrl¬ify_url=https%3A%2F%2Fiot.remacsmart.com%2Fwx%2Falipay%2Fgate%2FnotifyUrl&version=1.0&app_id=2021003167618019&sign_type=RSA2×tamp=2022-12-06+05%3A19%3A54&alipay_sdk=alipay-sdk-java-dynamicVersionNo&format=json\">\n<input type=\"hidden\" name=\"return_url\" value=\"https://iot.remacsmart.com/wx/alipay/gate/returnUrl\">\n<input type=\"hidden\" name=\"biz_content\" value=\"{"out_trade_no":"20211215143916AVGMAXUXN4","total_amount":"1","quit_url":"https://pay.remacsmart.com","subject":"alipay_web","timeout_express":"5m","body":"达达公司","product_code":"QUICK_WAP_WAY"}\">\n<input type=\"hidden\" name=\"notify_url\" value=\"https://iot.remacsmart.com/wx/alipay/gate/notifyUrl\">\n<input type=\"hidden\" name=\"quit_url\" value=\"https://pay.remacsmart.com\">\n<input type=\"submit\" value=\"立即支付\" style=\"display:none\" >\n</form>\n<script>document.forms[0].submit();</script>","success":true}
}
注:支付宝统一下单后,直接生成一个提交表单,自动唤起支付宝付款。
import { unifyOrder, grant } from '../../../api/';
var headers = { 'Content-Type':'application/json;charset=utf8', 'Authorization': token };
unifyOrder(this.form, headers).then((res) => {
document.write(res.data.data);
});
3.1.3 订单查询接口
本协议同时支持微信、支付宝订单结果查询
协议: https
URL: https://iot.remacsmart.com/wx/wechat/pay/result_query
method: post
http头部: {"Authorization": $Token}, Token 为 《1.2.2 由 code 换取微信access_token》接口返回的token值。
body:
字段 | 类型 | 是否必传 | 说明 |
---|---|---|---|
out_trade_no | String | 是 | 平台订单号,中台生成。 |
查询返回结果:
{
"code": "200",
"data": {
"pay_status": 2,
"trade_state": "TRADE_SUCCESS"
},
"message": "success"
}
返回属性说明
字段 | 类型 | 是否必返回 | 说明 |
---|---|---|---|
pay_status | Int | 是 | 订单当前的实际状态,见中台业务数据字典《2.3.3.2 pay_status 》 |
trade_state | String | 否 | 微信或支付宝的实际交易code |
3.1.4 退款接口
本协议同时支持微信、支付宝按订单号退款。V0.1版本仅支持支付宝退款。
协议: https
URL: https://iot.remacsmart.com/wx/wechat/pay/refund
method: post
http头部: {"Authorization": $Token}, Token 为 《1.2.2 由 code 换取微信access_token》接口返回的token值。
body:
字段 | 类型 | 是否必传 | 说明 |
---|---|---|---|
out_trade_no | String | 是 | 平台订单号,中台生成。 |
refund_amount | String | 是 | 退款金额,RMB单位:分。 |
退款成功返回结果:
{"code":"200","message":"XX"}
3.1.5 退款查询接口
本协议同时支持微信、支付宝按订单号退款查询。V0.1版本仅支持支付宝退款查询。
协议: https
URL: /wx/wechat/pay/refund/result_query
method: post
http头部: {"Authorization": $Token}, Token 为 《1.2.2 由 code 换取微信access_token》接口返回的token值。
body:
字段 | 类型 | 是否必传 | 说明 |
---|---|---|---|
out_trade_no | String | 是 | 平台订单号,中台生成。 |
退款成功返回结果:
{
"code": "200",
"data": {
"refund_status": "REFUND_SUCCESS",
"refund_amount": "0.01"
},
"message": "success"
}
3.1.6 交易关闭接口
本协议同时支持微信、支付宝按订单号关闭交易
协议: https
URL: /wx/wechat/pay/trade/close
method: post
http头部: {"Authorization": $Token}, Token 为 《1.2.2 由 code 换取微信access_token》接口返回的token值。
body:
字段 | 类型 | 是否必传 | 说明 |
---|---|---|---|
out_trade_no | String | 是 | 平台订单号,中台生成。 |
订单交易关闭成功返回结果:
{
"code": "200",
"message": "success"
}
3.1.7 微信支付后统一推送
当平台收到微信支付成功回调后,将订单支付状态的信息推送给第三方业务平台。此接口由第三方业务系统提供。
此接口将连续推送3次,第三方业务平台做好逻辑处理。
协议: https
URL: 第三方业务系统URL
method: post
body:
字段 | 类型 | 是否必传 | 说明 |
---|---|---|---|
out_trade_no | String | 是 | 平台订单号,中台生成。 |
business_order_id | String | 否 | 第三方业务系统 订单ID |
transaction_id | String | 是 | 微信交易流水ID |
extra | JSONObject | 否 | 透传给业务的JSON数据包 |
返回结果:
{"code":"200","message":"推送成功"}
由code 取值来判断支付情况 ,code返回值如下:
200:支付成功
REFUND:转入退款
NOTPAY:未支付
CLOSED:已关闭
REVOKED:已撤销(刷卡支付)
USERPAYING:用户支付中
PAYERROR:支付失败(其他原因,如银行返回失败)
置业集团睿住智能科技公司空间智能研究院_睿智云中台
3.1.8 收银台——保存订单前置表数据
说明: 业务端调起收银台页面之前,需要调用此接口进行订单前置数据保存。
URL: /wx/wechat/cashRegister/readyOrder
Method: GET
Body:
{
"business_id": XX, // 商户标识
"business_name":"XX", //商户名称
"goods_content":"XX", //商品详情
"goods_count":XX, //商品数量
"unit_price":XX, // 商品单价
"total_fee": XX, //商品总价
"business_order_no":"XX", //业务订单号,
"business_type":"XX", //业务平台标识,
"create_time":"XX", //创建时间,
"original":"XX" //调用来源(参考authen_type)
字段说明
字段 | 类型 | 是否必传 | 说明 |
---|---|---|---|
business_id | String | Y | 商户标识 |
business_name | String | N | 商户名称 |
goods_content | String | N | 商品详情 |
goods_count | Integer | Y | 商品数量 |
unit_price | Integer | Y | 商品单价 |
total_fee | Integer | Y | 商品总价 |
business_order_no | String | Y | 业务订单号 |
business_type | String | Y | 业务平台标识 |
create_time | String | N | 创建时间 |
original | String | Y | 参考authen_type |
3.1.9 收银台——加载收银台
说明: 支付中台的收银台页面打开时需调用此接口加载所需信息。
URL: /wx/wechat/cashRegister/loadCashRegister
Method: GET
Body:
{
"business_order_no":"XX", //业务订单号,
"business_type":"XX" //业务平台标识
字段说明
字段 | 类型 | 是否必传 | 说明 |
---|---|---|---|
business_order_no | String | Y | 业务订单号 |
business_type | String | Y | 业务平台标识 |
3.2 支付配置相关接口
注: 支付配置相关接口域名见《2.3.2 支付配置相关域名 》
3.2.1 商户或服务商主体信息新增/修改
说明: 中台服务商主体信息是平台全局配置信息,所有租户共享,不受租户数据隔离的约束。
URL: /wx/config/muchroot/update
Method: PUT
Body:
{
"much_root_id": XX, // 中台服务主体主键ID
"business_type":"XX",
"shop_name":"XX", //项目名称
"shop_id":XX, //项目ID,即空间ID
"company_name":"XX", // 商户主体
"sub_name": "XX", //商户名称
"sub_id":"XX", //商户号,
"wechat_pay_key":"XX",//商户支付密钥
"api_cert":"XXX",
"service_as": 1, //1:
"apps":[
{
"appid":"XX",
"appsecret":"XX",
"authen_type":"wechat"
},
{
"appid":"XX",
"appsecret":"XX",
"authen_type":"app",
"wechat_pay_key":"XX",//商户支付密钥
}
]
}
BODY:
字段说明
字段 | 类型 | 是否必传 | 说明 |
---|---|---|---|
much_root_id | Long | Y | 中台服务商主体信息表主键;为空代表新增,不为代表修改 |
apps | JSONObject | y | 应用列表 |
authen_type | String | 当前仅支持:wechat:微信公众号;app:app | |
shop_id | Long | Y | 业务方虚拟门店ID,由业务方提供,发起支付的标识,在业务方要唯一 。 |
shop_name | String | y | 业务方虚拟门店名称 |
business_type | String | N | 默认为community |
3.2.2 商户或服务商主体信息加载
说明: 会一次性加载项目下中台服务商主体信息much_root、商户公共参数 much_api 、关联开发者应用apps。
URL: /wx/config/muchroot/load/{shop_id}?business_type=XX
Method: GET
路径参数
shop_id: 业务方项目ID , 即《3.1.2 获取token》接口中的 space_id值。
请求参数
business_type: 见 《2.3.3.2 business_type》数据字典部分。社区业务可以不用传。
返回示例:
{
"much_root_id": XX, // 中台服务主体主键ID
"shop_name":"XX", //项目名称
"business_type":"XX",
"shop_id":XX, //项目ID,即空间ID,业务ID
"company_name":"XX", // 商户主体
"sub_name": "XX", //商户名称
"sub_id":"XX", //商户号
"wechat_pay_key":"XX",//商户支付密钥,APIV3
"api_cert":"XXX",
"apps":[
{
"id":XX,
"appid":"XX",
"appsecret":"XX",
"authen_type":"wechat"
},
{
"id":XX,
"appid":"XX",
"appsecret":"XX",
"authen_type":"app"
}
]
}
3.2.3 商户信息分页查询
说明:分页查询商户号记录,还可以根据项目shop_id来过滤查询。
URL: /wx/config/muchroot/page
Method: POST
商户公共参数 much_api : 各字段说明:
字段 | 类型 | 是否必传 | 说明 |
---|---|---|---|
shop_id | Long | N | 业务方虚拟门店ID |
key_word | String | N | 商户名称/商户号 |
pageNo | Int | N | 缺省值 1 |
pageSize | Int | N | 缺省值 20 |
返回示例:
{
"data": {
"pageNo":1, "pageSize": 20, "total":200, "totalPage": 10,
"result":[
{ "much_root_id": XX,
"shop_id": XX,
"shop_name": "XX",
"company_name": "XX",
"sub_name": "XX",
"sub_id": "XX"
}
]
}
}
3.2.4 服务商主体下子商户号分页查询
说明:分页查询服务商主体下子商户号记录,还可以根据项目shop_id来过滤查询。
URL: /wx/config/muchroot/subtenants/page
Method: POST
商户公共参数 much_api : 各字段说明:
字段 | 类型 | 是否必传 | 说明 |
---|---|---|---|
shop_id | Long | Y | 项目ID |
appid | String | N | 应用appid |
pageNo | Int | N | 缺省值 1 |
pageSize | Int | N | 缺省值 20 |
返回示例:
{
"data": {
"pageNo":1, "pageSize": 20, "total":200, "totalPage": 10,
"result":[
{"appid": "XX", "appsecret":"XX","authen_type": "wechat"}, ...
]
}
}
3.2.5 删除主体下项目及支付配置信息
说明:分页查询服务商主体下子商户号记录,还可以根据项目shop_id来过滤查询。
URL: /wx/config/muchroot/delete/{shop_id}
Method: DELETE
字段 | 类型 | 是否必传 | 说明 |
---|---|---|---|
shop_id | Long | Y | 项目ID |
3.2.6 获取已配置关联的项目列表
说明:获取已配置关联的项目列表。
URL: /wx/config/space/list
Method: POST
入参:无
返回示例:
{
"resCode": "200",
"resMsg": "发送成功",
"data": [
{
"space_id": "9",
"space_name": "erwer"
}
]
}
3.2.6 获取支付主体列表
说明:业务方需要从支付中台获取支付主体信息。
URL: /wx/config/muchroot/list
Method: Get
入参:无
返回示例:
{
"resCode": "200",
"resMsg": "发送成功",
"data": [
result: [
{much_root_id:xx, compnay_name: XX },
{much_root_id:YY, compnay_name: YY },
...
]
]
}
其中: much_root_id 为中台支付主体的主键ID。即文档中定义的“中台服务商主体表主键”。
参考资料:
支付宝APP支付API文档 :https://opendocs.alipay.com/open/02e7gq?scene=20
微信支付API文档:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_12&index=2&index=2
port=8030
pid=$(netstat -nlp | grep :$port | awk '{print $7}' | awk -F"/" '{print $1}')
if [ -n "$pid" ]; then
kill -9 $pid;
fi