移动订货在线支付插件概要说明
移动订货在线支付功能是提供给门店订货人员在移动订货App上进行在线实时支付的一个便捷功能。产品现已支持微信h5支付、支付宝支付、微信公众号支付、微信小程序支付。客户在使用中如有其他的第三方支付需求,可参考以下说明进行扩展。
一、创建一个移动订货在线支付插件
1. 创建移动订货在线支付插件类库
使用VS2012及以上版本的C#语言,创建一个Class Library项目:
2. 引用必要组件
到K/3 Cloud安装目录的WebSite\Bin子目录,引用如下组件:
Kingdee.BOS.dll
Kingdee.BOS.DataEntity.dll
Kingdee.K3.DE.Mobile.Common.Core.dll
Kingdee.K3.DE.SCM.Common.BusinessEntity.dll
Kingdee.K3.DE.SCM.Common.Core.dll
Kingdee.K3.DE.SCM.App.Core.dll
3. 创建移动订货在线支付插件类
在前文所建的移动订货在线支付插件工程中,添加新类,派生自移动订货在线支付基类:Kingdee.K3.DE.SCM.App.Core.OnlinePay.AbstractPay,编译部署该插件工程到金蝶云星空应用服务器中。
支付基类:
二、启用移动订货在线支付插件
1. 新建对应结算方式并配置自定义插件类
登录系统,打开【基础管理-基础资料-财务会计-结算方式】菜单,新增结算方式
2. 配置门店移动订货支付方式
登录系统,打开【餐饮门店管理-门店订货管理-基础资料-门店移动订货支付方式】菜单,新增门店移动订货支付方式
3. 配置总部收款账户信息
登录系统,打开【餐饮门店管理-门店订货管理-基础资料-总部收款账户】菜单,新增总部收款账户
4. 配置支付结果通知接口
前置补丁要求: PT-001846 [Kingdee Cloud CY V7 SP.8.0.1114.1]
打开配置文件\K3Cloud\WebSite\App_Data\ Common.config
在appSettings节点下增加以下节点:
<add key="回调地址" value="支付插件(类的全限定名+英文逗号+程序集名)" />
提供给支付系统的支付结果通知接口:
http://cloud服务器域名/K3Cloud/回调地址/mobile.cymcbapi
注:上述两个回调地址的大小写必须保持一致
示例:
<appSettings>
<add key="KDPayCallBack" value="Kingdee.K3.DE.SCM.App.Core.OnlinePay.BaseKDPay, Kingdee.K3.DE.SCM.App.Core" />
</appSettings>
提供给支付系统的支付结果通知接口:
http://www.kingdee.com/ K3Cloud/KDPayCallBack/mobile.cymcbapi
三、插件基类的虚方法说明
1. Pay
移动订货在线支付方法,在该方法内调用支付平台接口进行支付下单操作,支付平台处理后返回跳转URL给前端,前端得到URL后跳转到支付平台进行支付。
虚方法定义:
public virtual PayResult Pay(Context ctx, PayParameter payParm, HttpContext httpContext)
参数介绍:PayParameter | ||
属性 | 类型 | 描述 |
OrgId | long | 组织内码 |
DeptId | long | 部门内码,暂不使用 |
FormId | string | 业务单据标志 |
SrcBillId | long | 业务单据内码 |
PayType | int | 支付模式,枚举值: 0:微信h5支付 1:支付宝支付 2:微信公众号支付 3:微信小程序 9:自定义线上支付 10:其他支付 备注:自定义的都为其他支付 |
PayAmount | decimal | 支付金额,单位为元 |
OperateSystem | string | 移动平台:IOS、Android |
MobileAppType | int | 移动APP平台,枚举值: 1:微信 2:云之家 3:企业微信 4:钉钉 5:微信小程序
|
SettleTypeId | int | 结算方式内码 |
MerOrderId | string | 商户订单号 |
OrderName | string | 商品名称 |
ReceiptAccountId | int | 总部收款账户内码 |
返回结果参数介绍:QueryOrderResult | ||
属性 | 类型 | 描述 |
MerOrderId | string | 商户订单号 |
PayUrl | string | 支付跳转链接,可通过访问该PayUrl来拉起微信客户端、支付宝客户端或者其他客户端,完成支付 |
TransStatus | string | 支付状态 00:未支付 01:支付成功 10:订单关闭 02:支付失败 03:已下单 04:申请退款 05:退款成功 06:退款失败 07:订单撤销 |
WeixinJsapi | string | 微信小程序支付信息,专用于微信小程序支付 |
2. QueryOrder
查询订单方法,主动查询订单状态。此方法通常提供给前端在支付完成后进行订单状态的查询操作。
虚方法定义:
public virtual QueryOrderResult QueryOrder(Context ctx, QueryOrderParameter queryParm, HttpContext httpContext)
参数介绍:QueryOrderParameter | ||
属性 | 类型 | 描述 |
OrgId | long | 组织内码 |
DeptId | long | 部门内码,暂不使用 |
MerOrderId | string | 商户订单号 |
ReceiptAccountId | int | 总部收款账户内码 |
返回结算参数介绍:QueryOrderResult | ||
属性 | 类型 | 描述 |
MerOrderId | string | 商户订单号 |
TransStatus | string | 支付状态 00:未支付 01:支付成功 10:订单关闭 02:支付失败 03:已下单 04:申请退款 05:退款成功 06:退款失败 07:订单撤销 |
TransDate | string | 支付时间,格式为YYYYMMDDHHMMSS |
Attach | string | 备注字段,按照请求参数原样返回 |
PayChannel | string | 支付渠道 如:weixinpay、alipay |
ChannelName | string | 支付渠道名 |
TransAmt | decimal | 交易金额,单位为元 |
TradeOrderId | string | 支付系统生成的订单号,如微信订单号、支付宝订单号 |
3. Refund
退款申请方法,可以继承该方法实现将支付金额退还给买家,一般支付平台在收到退款请求并且验证成功之后,将支付款按原路退还至买家帐号上。
虚方法定义:
public virtual RefundResult Refund(Context ctx, RefundParameter refundParm, HttpContext httpContext)
参数介绍:RefundParameter | ||
属性 | 类型 | 描述 |
MerOrderId | string | 商户订单号 |
RefundOrderId | string | 商户退款请求订单号 |
RefundAmt | decimal | 退款金额,单位为元 |
RefundReason | string | 退款理由 |
ReceiptAccountId | int | 总部收款账户内码 |
返回结算参数介绍:RefundResult | ||
属性 | 类型 | 描述 |
MerOrderId | string | 商户订单号 |
RefundOrderId | string | 商户退款请求订单号 |
TransStatus | string | 支付状态 00:未支付 01:支付成功 10:订单关闭 02:支付失败 03:已下单 04:申请退款 05:退款成功 06:退款失败 07:订单撤销 |
RefundAmt | decimal | 退款金额,单位为元 |
TransAmt | decimal | 原订单交易金额,单位为元 |
4. QueryRefund
提交退款申请后,可以通过继承该方法实现查询退款状态。
虚方法定义:
public virtual QueryRefundResult QueryRefund(Context ctx, QueryRefundParameter queryParm, HttpContext httpContext)
参数介绍:QueryRefundParameter | ||
属性 | 类型 | 描述 |
MerOrderId | string | 商户订单号 |
RefundOrderId | string | 商户退款请求订单号 |
ReceiptAccountId | int | 总部收款账户内码 |
返回结算参数介绍:QueryRefundResult | ||
属性 | 类型 | 描述 |
MerOrderId | string | 商户订单号 |
RefundOrderId | string | 商户退款请求订单号 |
TransStatus | string | 支付状态 00:未支付 01:支付成功 10:订单关闭 02:支付失败 03:已下单 04:申请退款 05:退款成功 06:退款失败 07:订单撤销 |
RefundAmt | decimal | 退款金额,单位为元 |
TransAmt | decimal | 原订单交易金额,单位为元 |
TradeOrderId | string | 支付系统生成的订单号,如微信订单号、支付宝订单号 |
ChannelName | string | 支付渠道名 |
5. PayCallBackParseData
支付系统调用支付结果通知接口后,需要经过解密请求数据、处理系统单据、响应请求这三个步骤。通过继承该方法,实现对请求数据的解密。
虚方法定义:
public virtual PayCallBackParseResult PayCallBackParseData(HttpContext httpContext)
返回参数介绍:PayCallBackParseResult | ||
属性 | 类型 | 描述 |
IsSuccess | bool | 成功与否 |
Message | string | 返回信息 |
BOSContext | Context | BOS上下文 |
PayCallBackParam | PayCallBackParameter | 支付结果通知参数 |
返回参数介绍:PayCallBackParameter | ||
属性 | 类型 | 描述 |
MerOrderId | string | 商户订单号 |
TransStatus | string | 支付状态 00:未支付 01:支付成功 10:订单关闭 02:支付失败 03:已下单 04:申请退款 05:退款成功 06:退款失败 07:订单撤销 |
ExtraInfo | object | 附加信息,会原样携带到PayCallBackResponse方法中 |
6. PayCallBackResponse
支付系统调用支付结果通知接口后,需要经过解密请求数据、处理系统单据、响应请求这三个步骤。通过继承该方法,实现对响应数据的加密,并响应请求。
虚方法定义:
public virtual void PayCallBackResponse(Context ctx, HttpContext httpContext, PayCallBackHandleResult payCallBackHanldeResult)
参数介绍:PayCallBackHandleResult | ||
属性 | 类型 | 描述 |
IsSuccess | bool | 成功与否 |
Message | string | 返回信息 |
PayCallBackParam | PayCallBackParameter | 支付结果通知参数 |
三、代码示例
1. 支付结果通知接口
using Kingdee.BOS;
using Kingdee.K3.DE.SCM.App.Core.OnlinePay;
using Kingdee.K3.DE.SCM.Common.BusinessEntity;
using System.Web;
namespace PayTest.OnlinePay
{
/// <summary>
/// 自定义支付插件
/// </summary>
public class CustomPay : AbstractPay
{
public override PayCallBackParseResult PayCallBackParseData(HttpContext httpContext)
{
// 获取请求参数
object requestParam = null;
// 解密请求参数
object data = null;
// 一般支付系统的下单接口,都有一个附加字段的参数。当支付系统调用我们的支付结果通知接口时,会原样返回该附加字段。
// 这里建议,在下单接口,用UserToken缓存好BOS上下文,并将UserToken作为附加字段,加密后传给支付系统。
// 然后在这里拿到请求参数中的附加字段,解密后拿到UserToken,接着就可以从缓存里取出BOS上下文。
// 缓存时间可根据支付系统调用该接口的频率来定。
Context ctx = null;
// 封装解密结果
PayCallBackParseResult parseResult = new PayCallBackParseResult();
// 解密成功与否
parseResult.IsSuccess = true;
// 解密失败,该信息会携带到PayCallBackRespons方法中
parseResult.Message = "";
// BOS上下文
parseResult.BOSContext = ctx;
// 解密得到的数据,该PayCallBackParam会携带到PayCallBackRespons方法中
parseResult.PayCallBackParam = new PayCallBackParameter();
// 支付状态
parseResult.PayCallBackParam.TransStatus = "";
// 商户订单号
parseResult.PayCallBackParam.MerOrderId = "";
// 附加信息,用于携带信息到PayCallBackResponse方法中
parseResult.PayCallBackParam.ExtraInfo = null;
return parseResult;
}
public override void PayCallBackResponse(Context ctx, HttpContext httpContext, PayCallBackHandleResult payCallBackHanldeResult)
{
// 数据解密结果的PayCallBackParam
PayCallBackParameter payCallBackParam = payCallBackHanldeResult.PayCallBackParam;
// 附加信息
object extraInfo = payCallBackParam.ExtraInfo;
// 根据系统处理结果,决定响应的内容
string returnStr = string.Empty;
if (payCallBackHanldeResult.IsSuccess)
{
}
else
{
}
// 响应请求
httpContext.Response.Write(returnStr);
}
}
}