Skip to content

Commit

Permalink
feat: add wechat pay transaction jsapi order v3 interface
Browse files Browse the repository at this point in the history
  • Loading branch information
jay committed Jun 25, 2022
1 parent 712152a commit 4de65d0
Show file tree
Hide file tree
Showing 3 changed files with 206 additions and 1 deletion.
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,10 @@ dist

*.local

demo.ts
demo.ts

# wepay private key
apiclient_key.pem

# This has secret data
wepay.service.spec.ts
8 changes: 8 additions & 0 deletions lib/wechat.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
import { MiniProgramService } from './miniprogram.service';
import { ICache } from './types/utils';
import { MapCache } from './utils/cache';
import { WePayService } from './wepay.service';

@Injectable()
export class WeChatService {
Expand All @@ -26,6 +27,12 @@ export class WeChatService {
protected _cacheAdapter: ICache = new MapCache();

public mp: MiniProgramService;
/**
* WePay Service
* @type {WePayService}
* @memberof WeChatService
*/
public pay: WePayService;

public set cacheAdapter (adapter: ICache) {
if (adapter) {
Expand All @@ -38,6 +45,7 @@ export class WeChatService {

constructor (private options: WeChatModuleOptions) {
this.mp = new MiniProgramService(options);
this.pay = new WePayService();
if (options && options.cacheAdapter) {
this.cacheAdapter = options.cacheAdapter as ICache;
}
Expand Down
191 changes: 191 additions & 0 deletions lib/wepay.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
import { Injectable, Logger } from '@nestjs/common';
import axios from 'axios';
import * as crypto from 'crypto';

import { createNonceStr } from './utils';

/**
* JSAPI Order Data Interface
*/
export interface TransactionOrder {
/**
* 应用ID
* 长度32
*/
appid: string;
/**
* 直连商户号
* 长度32
*/
mchid: string;
/**
* 商品描述
* 长度127
*/
description: string;
/**
* 商户订单号
* 长度32
*/
out_trade_no: string;
/**
* 交易结束时间
* yyyy-MM-DDTHH:mm:ss+TIMEZONE
* 例如:2015-05-20T13:29:35+08:00表示,北京时间2015年5月20日 13点29分35秒
* 长度64
*/
time_expire?: string;
/**
* 附加数据
* 长度128
*/
attach?: string;
/**
* 通知地址
* 长度256
*/
notify_url: string;
/**
* 订单优惠标记
* 长度32
*/
goods_tag?: string;
/**
* 订单金额
*/
amount: {
/**
* 总金额,单位:分
*/
total: number
/**
* 货币类型,如:CNY
* 长度16
*/
currency: string,
};
/**
* 支付者
*/
payer: {
/**
* OPENID
* 长度128
*/
openid: string;
}
detail?: {
/**
* 订单原价
*/
cost_price?: number;

/**
* 商品小票ID
* 长度32
*/
invoice_id?: string;
goods_detail?: {
/**
* 商户侧商品编码
* 长度32
*/
merchant_goods_id: string;
/**
* 微信支付商品编码
* 长度32
*/
wechatpay_goods_id?: string;
/**
* 商品名称
* 长度256
*/
goods_name?: string;
/**
* 商品数量
* 长度32
*/
quantity: number;
/**
* 商品单价,单位分
*/
unit_price: number;
}[];
};
/**
* 场景信息
*/
scene_info?: {
/**
* 用户终端IP
* 长度45
*/
payer_client_ip: string;
/**
* 商户端设备号
* 长度32
*/
device_id?: string;
/**
* 商户门店信息
*/
store_info?: {
/**
* 门店编号
* 长度32
*/
id: string;
/**
* 门店名称
* 长度256
*/
name?: string;
/**
* 地区编码
* 长度32
*/
area_code?: string;
/**
* 详细地址
* 长度512
*/
address?: string;
};
};
/**
* 结算信息
*/
settle_info?: {
/**
* 是否指定分账
*/
profit_sharing?: boolean;
}
}

@Injectable()
export class WePayService {

private readonly logger = new Logger(WePayService.name);

/**
* JSAPI下单
* @param order 下单信息
* @param serialNo 私钥序列号
* @param privateKey 私钥
* @returns
* @link https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_1.shtml
*/
async transactionsJsapi (order: TransactionOrder, serialNo: string, privateKey: Buffer | string) {
const nonceStr = createNonceStr();
const timestamp = Math.floor(Date.now() / 1000);
const message = `POST\n/v3/pay/transactions/jsapi\n${timestamp}\n${nonceStr}\n${JSON.stringify(order)}\n`;
const signature = crypto.createSign('sha256WithRSAEncryption').update(message).sign(privateKey, 'base64');
const url = 'https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi';
return await axios.post(url, order, {
headers: {
'Authorization': `WECHATPAY2-SHA256-RSA2048 mchid="${order.mchid}",nonce_str="${nonceStr}",signature="${signature}",timestamp="${timestamp}",serial_no="${serialNo}"`,
},
});
}
}

0 comments on commit 4de65d0

Please sign in to comment.