@jayfong/x-server 2.5.0 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -94,20 +94,80 @@ class PayService {
94
94
 
95
95
  verifyNotifyData(data) {
96
96
  try {
97
- var _this$alipaySdk;
97
+ if (!data || typeof data !== 'object') {
98
+ return false;
99
+ } // 支付宝
100
+ // https://opendocs.alipay.com/open/270/105902
98
101
 
99
- return !!data && typeof data === 'object' && ( // 支付宝
100
- data.passback_params === 'alipay' ? !!((_this$alipaySdk = this.alipaySdk) != null && _this$alipaySdk.checkNotifySign(data)) : // 微信支付
101
- data.resource ? JSON.parse(this.wepayDecrypt(data.resource)).attach === 'wepay' : false);
102
+
103
+ if (data.passback_params === 'alipay') {
104
+ var _this$alipaySdk;
105
+
106
+ if (!((_this$alipaySdk = this.alipaySdk) != null && _this$alipaySdk.checkNotifySign(data))) {
107
+ return false;
108
+ }
109
+
110
+ return {
111
+ channelOrderNo: data.trade_no
112
+ };
113
+ } // 微信支付
114
+ // https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_5.shtml
115
+
116
+
117
+ if (data.resource) {
118
+ const params = JSON.parse(this.wepayDecrypt(data.resource));
119
+
120
+ if (params.attach === 'wepay') {
121
+ return {
122
+ channelOrderNo: params.transaction_id
123
+ };
124
+ }
125
+
126
+ return false;
127
+ }
128
+
129
+ return false;
102
130
  } catch {
103
131
  return false;
104
132
  }
105
133
  }
106
134
 
107
135
  verifyNotifyDataOrFail(data, message) {
108
- if (!this.verifyNotifyData(data)) {
136
+ const res = this.verifyNotifyData(data);
137
+
138
+ if (!res) {
109
139
  throw new _http_error.HttpError.BadRequest(message);
110
140
  }
141
+
142
+ return res;
143
+ }
144
+
145
+ async getOrderInfo(payload) {
146
+ // 微信支付
147
+ // https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_2.shtml
148
+ if (payload.channel === 'wepay') {
149
+ const res = await this.wepayRequest(payload.orderNo ? `https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/${payload.orderNo}?mchid=${this.options.wepay.merchantId}` : `https://api.mch.weixin.qq.com/v3/pay/transactions/id/${payload.channelOrderNo}?mchid=${this.options.wepay.merchantId}`);
150
+ return {
151
+ channelOrderNo: res.transaction_id,
152
+ orderNo: res.out_trade_no,
153
+ status: res.trade_state === 'SUCCESS' ? 'success' : 'fail'
154
+ };
155
+ } // 支付宝
156
+ // https://opendocs.alipay.com/open/028woa?scene=common&pathHash=dbf247eb
157
+
158
+
159
+ const res = await this.alipaySdk.exec('alipay.trade.query', {
160
+ biz_content: payload.orderNo ? {
161
+ out_trade_no: payload.orderNo
162
+ } : {
163
+ trade_no: payload.channelOrderNo
164
+ }
165
+ });
166
+ return {
167
+ channelOrderNo: res.trade_no,
168
+ orderNo: res.out_trade_no,
169
+ status: res.trade_status === 'TRADE_SUCCESS' || res.trade_status === 'TRADE_FINISHED' ? 'success' : 'fail'
170
+ };
111
171
  }
112
172
 
113
173
  wepaySign(data) {
@@ -130,9 +190,10 @@ class PayService {
130
190
 
131
191
  async wepayRequest(url, data) {
132
192
  const path = url.replace(/^https?:\/\/[^/]+/, '');
133
- const body = JSON.stringify(data);
193
+ const method = data == null ? 'GET' : 'POST';
194
+ const body = method === 'POST' ? JSON.stringify(data) : '';
134
195
  const params = {
135
- method: 'POST',
196
+ method: method,
136
197
  url: path,
137
198
  time: String(Math.round(Date.now() / 1000)),
138
199
  rand: Math.random().toString().substr(2, 12),
@@ -141,13 +202,19 @@ class PayService {
141
202
  };
142
203
  params.signature = this.wepaySign([params.method, params.url, params.time, params.rand, params.body]);
143
204
  const Authorization = [`WECHATPAY2-SHA256-RSA2048 `, `mchid="${this.options.wepay.merchantId}",`, `nonce_str="${params.rand}",`, `signature="${params.signature}",`, `timestamp="${params.time}",`, `serial_no="${this.options.wepay.certificateSerialNumber}"`].join('');
144
- const res = await _got.default.post(url, {
205
+ const res = method === 'POST' ? await _got.default.post(url, {
145
206
  json: data,
146
207
  headers: {
147
208
  Authorization
148
209
  },
149
210
  responseType: 'json',
150
211
  resolveBodyOnly: true
212
+ }) : await _got.default.get(url, {
213
+ headers: {
214
+ Authorization
215
+ },
216
+ responseType: 'json',
217
+ resolveBodyOnly: true
151
218
  });
152
219
  return res;
153
220
  }
@@ -64,6 +64,46 @@ export interface PayServicePrepareWepayResult {
64
64
  paySign: string;
65
65
  };
66
66
  }
67
+ export interface PayServiceVerifyNotifyDataResult {
68
+ /**
69
+ * 渠道订单号。
70
+ *
71
+ * - 支付宝最长 `64` 位;
72
+ * - 微信支付最长 `32` 位。
73
+ */
74
+ channelOrderNo: string;
75
+ }
76
+ export interface PayServiceGetOrderInfoPayload {
77
+ /**
78
+ * 渠道。
79
+ */
80
+ channel: 'alipay' | 'wepay';
81
+ /**
82
+ * 商家订单号。
83
+ */
84
+ orderNo?: string;
85
+ /**
86
+ * 渠道订单号。
87
+ */
88
+ channelOrderNo?: string;
89
+ }
90
+ export interface PayServiceGetOrderInfoResult {
91
+ /**
92
+ * 商家订单号。
93
+ */
94
+ orderNo: string;
95
+ /**
96
+ * 渠道订单号。
97
+ *
98
+ * - 支付宝最长 `64` 位;
99
+ * - 微信支付最长 `32` 位。
100
+ */
101
+ channelOrderNo: string;
102
+ /**
103
+ * 订单状态。
104
+ */
105
+ status: 'success' | 'fail';
106
+ }
67
107
  export declare class PayService implements BaseService {
68
108
  private options;
69
109
  serviceName: string;
@@ -71,8 +111,9 @@ export declare class PayService implements BaseService {
71
111
  constructor(options: PayServiceOptions);
72
112
  prepareAlipay(options: PayServicePrepareAlipayOptions): Promise<PayServicePrepareAlipayResult>;
73
113
  prepareWepay(options: PayServicePrepareWepayOptions): Promise<PayServicePrepareWepayResult>;
74
- verifyNotifyData(data: any): boolean;
75
- verifyNotifyDataOrFail(data: any, message?: string): void;
114
+ verifyNotifyData(data: any): false | PayServiceVerifyNotifyDataResult;
115
+ verifyNotifyDataOrFail(data: any, message?: string): PayServiceVerifyNotifyDataResult;
116
+ getOrderInfo(payload: PayServiceGetOrderInfoPayload): Promise<PayServiceGetOrderInfoResult>;
76
117
  private wepaySign;
77
118
  private wepayDecrypt;
78
119
  private wepayRequest;
@@ -82,20 +82,80 @@ export class PayService {
82
82
 
83
83
  verifyNotifyData(data) {
84
84
  try {
85
- var _this$alipaySdk;
85
+ if (!data || typeof data !== 'object') {
86
+ return false;
87
+ } // 支付宝
88
+ // https://opendocs.alipay.com/open/270/105902
86
89
 
87
- return !!data && typeof data === 'object' && ( // 支付宝
88
- data.passback_params === 'alipay' ? !!((_this$alipaySdk = this.alipaySdk) != null && _this$alipaySdk.checkNotifySign(data)) : // 微信支付
89
- data.resource ? JSON.parse(this.wepayDecrypt(data.resource)).attach === 'wepay' : false);
90
+
91
+ if (data.passback_params === 'alipay') {
92
+ var _this$alipaySdk;
93
+
94
+ if (!((_this$alipaySdk = this.alipaySdk) != null && _this$alipaySdk.checkNotifySign(data))) {
95
+ return false;
96
+ }
97
+
98
+ return {
99
+ channelOrderNo: data.trade_no
100
+ };
101
+ } // 微信支付
102
+ // https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_5.shtml
103
+
104
+
105
+ if (data.resource) {
106
+ const params = JSON.parse(this.wepayDecrypt(data.resource));
107
+
108
+ if (params.attach === 'wepay') {
109
+ return {
110
+ channelOrderNo: params.transaction_id
111
+ };
112
+ }
113
+
114
+ return false;
115
+ }
116
+
117
+ return false;
90
118
  } catch {
91
119
  return false;
92
120
  }
93
121
  }
94
122
 
95
123
  verifyNotifyDataOrFail(data, message) {
96
- if (!this.verifyNotifyData(data)) {
124
+ const res = this.verifyNotifyData(data);
125
+
126
+ if (!res) {
97
127
  throw new HttpError.BadRequest(message);
98
128
  }
129
+
130
+ return res;
131
+ }
132
+
133
+ async getOrderInfo(payload) {
134
+ // 微信支付
135
+ // https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_2.shtml
136
+ if (payload.channel === 'wepay') {
137
+ const res = await this.wepayRequest(payload.orderNo ? `https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/${payload.orderNo}?mchid=${this.options.wepay.merchantId}` : `https://api.mch.weixin.qq.com/v3/pay/transactions/id/${payload.channelOrderNo}?mchid=${this.options.wepay.merchantId}`);
138
+ return {
139
+ channelOrderNo: res.transaction_id,
140
+ orderNo: res.out_trade_no,
141
+ status: res.trade_state === 'SUCCESS' ? 'success' : 'fail'
142
+ };
143
+ } // 支付宝
144
+ // https://opendocs.alipay.com/open/028woa?scene=common&pathHash=dbf247eb
145
+
146
+
147
+ const res = await this.alipaySdk.exec('alipay.trade.query', {
148
+ biz_content: payload.orderNo ? {
149
+ out_trade_no: payload.orderNo
150
+ } : {
151
+ trade_no: payload.channelOrderNo
152
+ }
153
+ });
154
+ return {
155
+ channelOrderNo: res.trade_no,
156
+ orderNo: res.out_trade_no,
157
+ status: res.trade_status === 'TRADE_SUCCESS' || res.trade_status === 'TRADE_FINISHED' ? 'success' : 'fail'
158
+ };
99
159
  }
100
160
 
101
161
  wepaySign(data) {
@@ -116,9 +176,10 @@ export class PayService {
116
176
 
117
177
  async wepayRequest(url, data) {
118
178
  const path = url.replace(/^https?:\/\/[^/]+/, '');
119
- const body = JSON.stringify(data);
179
+ const method = data == null ? 'GET' : 'POST';
180
+ const body = method === 'POST' ? JSON.stringify(data) : '';
120
181
  const params = {
121
- method: 'POST',
182
+ method: method,
122
183
  url: path,
123
184
  time: String(Math.round(Date.now() / 1000)),
124
185
  rand: Math.random().toString().substr(2, 12),
@@ -127,13 +188,19 @@ export class PayService {
127
188
  };
128
189
  params.signature = this.wepaySign([params.method, params.url, params.time, params.rand, params.body]);
129
190
  const Authorization = [`WECHATPAY2-SHA256-RSA2048 `, `mchid="${this.options.wepay.merchantId}",`, `nonce_str="${params.rand}",`, `signature="${params.signature}",`, `timestamp="${params.time}",`, `serial_no="${this.options.wepay.certificateSerialNumber}"`].join('');
130
- const res = await got.post(url, {
191
+ const res = method === 'POST' ? await got.post(url, {
131
192
  json: data,
132
193
  headers: {
133
194
  Authorization
134
195
  },
135
196
  responseType: 'json',
136
197
  resolveBodyOnly: true
198
+ }) : await got.get(url, {
199
+ headers: {
200
+ Authorization
201
+ },
202
+ responseType: 'json',
203
+ resolveBodyOnly: true
137
204
  });
138
205
  return res;
139
206
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jayfong/x-server",
3
- "version": "2.5.0",
3
+ "version": "2.7.0",
4
4
  "license": "ISC",
5
5
  "sideEffects": false,
6
6
  "main": "lib/_cjs/index.js",