Skip to content

Commit

Permalink
feat(wepay): add refund interface
Browse files Browse the repository at this point in the history
  • Loading branch information
jay committed Jun 26, 2022
1 parent 23b9021 commit e8a36fc
Show file tree
Hide file tree
Showing 3 changed files with 339 additions and 13 deletions.
292 changes: 291 additions & 1 deletion lib/types/wepay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -399,4 +399,294 @@ export interface TradeGood {
* 商品备注信息
*/
goods_remark?: string;
}
}

/**
* 申请退款参数
*/
export interface RefundParameters {
/**
* 微信支付订单号
*/
transaction_id: string;
/**
* 商户订单号
*/
out_trade_no: string;
/**
* 商户退款单号
* 商户系统内部的退款单号,商户系统内部唯一,只能是数字、大小写字母_-|*@ ,同一退款单号多次请求只退一笔。示例值:1217752501201407033233368018
* 长度64
*/
out_refund_no: string;
/**
* 退款原因
* 若商户传入,会在下发给用户的退款消息中体现退款原因
*/
reason?: string;
/**
* 退款结果回调url
*/
notify_url?: string;
/**
* 退款资金来源
*/
funds_account?: 'AVAILABLE';
/**
* 金额信息
*/
amount: {
/**
* 退款金额,单位为分,只能为整数,不能超过原订单支付金额。
*/
refund: number;
/**
* 退款出资账户及金额
*/
from?: {
/**
* 出资账户类型
*/
account: 'AVAILABLE' | 'UNAVAILABLE';
/**
* 对应账户出资金额
*/
amount: number;
}[];
/**
* 原订单金额
*/
total: number;
currency: 'CNY';
};
/**
* 退款商品
* 指定商品退款需要传此参数,其他场景无需传递
*/
goods_detail?: RefundGoodDetail[];
}

export interface RefundGoodDetail {
/**
* 商户侧商品编码
*/
merchant_goods_id: string;
/**
* 微信支付商品编码
*/
wechatpay_goods_id?: string;
goods_name?: string;
/**
* 商品单价金额,单位为分
*/
unit_price: number;
/**
* 商品退款金额,单位为分
*/
refund_amount: number;
/**
* 单品的退款数量
*/
refund_quantity: number;
}

export interface RefundResult {
/**
* 微信支付退款单号
*/
refund_id: string;
/**
* 商户退款单号
*/
out_refund_no: string;
/**
* 微信支付订单号
*/
transaction_id: string;
/**
* 商户订单号
*/
out_trade_no: string;
/**
* 退款渠道
*/
channel: RefundChannel;
/**
* 退款入账账户
* 取当前退款单的退款入账方,有以下几种情况:
* 1)退回银行卡:{银行名称}{卡类型}{卡尾号}
* 2)退回支付用户零钱:支付用户零钱
* 3)退还商户:商户基本账户商户结算银行账户
* 4)退回支付用户零钱通:支付用户零钱通
* 示例值:招商银行信用卡0403
*/
user_received_account: string;
/**
* 退款成功时间,当退款状态为退款成功时有返回。
* 示例值:2020-12-01T16:18:12+08:00
*/
success_time?: string;
/**
* 退款创建时间
* 示例值:2020-12-01T16:18:12+08:00
*/
create_time: string;
/**
* 退款状态
*/
status: RefundStatus;
/**
* 资金账户
*/
funds_account?: FundsAccount;
/**
* 金额信息
*/
amount: {
/**
* 订单金额
*/
total: number;
/**
* 退款金额
*/
refund: number;
/**
* 退款出资账户及金额
*/
from?: {
/**
* 出资账户类型
*/
account: 'AVAILABLE' | 'UNAVAILABLE';
/**
* 对应账户出资金额
*/
amount: number;
}[];
/**
* 用户支付金额
*/
payer_total: number;
/**
* 用户退款金额
*/
payer_refund: number;
/**
* 应结退款金额
*/
settlement_refund: number;
/**
* 应结订单金额
*/
settlement_total: number;
/**
* 优惠退款金额
*/
discount_refund: number;
/**
* 退款币种
*/
currency: 'CNY';
};
/**
* 优惠退款信息
*/
promotion_detail?: {
/**
* 券ID
*/
promotion_id: string;
/**
* 优惠范围
*/
scope: 'GLOBAL' | 'SINGLE';
/**
* 优惠类型
*/
type: string;
/**
* 优惠券面额
*/
amount: number;
/**
* 优惠退款金额
*/
refund_amount: number;
/**
* 商品列表
*/
goods_detail?: RefundGoodDetail[];
}[];

}

/**
* 退款状态
*/
export enum RefundStatus {
/**
* 退款成功
*/
SUCCESS = 'SUCCESS',
/**
* 退款关闭
*/
CLOSED = 'CLOSED',
/**
* 退款处理中
*/
PROCESSING = 'PROCESSING',
/**
* 退款异常
*/
ABNORMAL = 'ABNORMAL',
}

/**
* 资金账户
*/
export enum FundsAccount {
/**
* 未结算资金
*/
UNSETTLED = 'UNSETTLED',
/**
* 可用余额
*/
AVAILABLE = 'AVAILABLE',
/**
* 不可用余额
*/
UNAVAILABLE = 'UNAVAILABLE',
/**
* 运营户
*/
OPERATION = 'OPERATION',
/**
* 基本账户(含可用余额和不可用余额)
*/
BASIC = 'BASIC',
}

/**
* 退款渠道
*/
export enum RefundChannel {
/**
* 原路退款
*/
ORIGINAL = 'ORIGINAL',
/**
* 退回到余额
*/
BALANCE = 'BALANCE',
/**
* 原账户异常退到其他余额账户
*/
OTHER_BALANCE = 'OTHER_BALANCE',
/**
* 原银行卡异常退到其他银行卡
*/
OTHER_BANKCARD = 'OTHER_BANKCARD'
}
16 changes: 15 additions & 1 deletion lib/wepay.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ describe('WePayService Test(Unit)', () => {
let privateKey: Buffer;
let publicKey: Buffer;

let outTradeNo = '';

beforeAll(() => {
outTradeNo = mchId + Math.random().toString().slice(3);
service = new WePayService();
privateKey = fs.readFileSync(path.join(__dirname, '..', 'apiclient_key.pem'));
publicKey = fs.readFileSync(path.join(__dirname, '..', 'apiclient_cert.pem'));
Expand All @@ -36,7 +39,7 @@ describe('WePayService Test(Unit)', () => {
appid: appId,
mchid: mchId,
description: '测试商品',
out_trade_no: '2022062518371669087377437861',
out_trade_no: outTradeNo,
notify_url: notifyUrl,
amount: {
total: 1,
Expand Down Expand Up @@ -70,4 +73,15 @@ describe('WePayService Test(Unit)', () => {
expect(certs[0].sn).toBeDefined();
});

it('Should get one trade by out trade no', async () => {
const ret = await service.getTransactionByOutTradeNo(outTradeNo, mchId, serial, privateKey);
expect(ret.data).toBeDefined();
expect(ret.data.out_trade_no).toStrictEqual(outTradeNo);
});

it('Should close one trade', async () => {
const ret = await service.close(outTradeNo, mchId, serial, privateKey);
expect(ret.status).toStrictEqual(204);
});

});
Loading

0 comments on commit e8a36fc

Please sign in to comment.