@waffo/waffo-node 2.0.3 → 2.0.4
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.
- package/LICENSE +1 -1
- package/README.md +1063 -390
- package/dist/index.d.mts +1567 -4258
- package/dist/index.d.ts +1567 -4258
- package/dist/index.js +1128 -1597
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1105 -1560
- package/dist/index.mjs.map +1 -1
- package/package.json +28 -43
- package/README.ja.md +0 -588
- package/README.zh-CN.md +0 -588
package/package.json
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@waffo/waffo-node",
|
|
3
|
-
"version": "2.0.
|
|
4
|
-
"description": "Official Node.js SDK
|
|
3
|
+
"version": "2.0.4",
|
|
4
|
+
"description": "Official Waffo PSP Node.js SDK",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
|
-
"files": [
|
|
9
|
-
"dist"
|
|
10
|
-
],
|
|
11
8
|
"exports": {
|
|
12
9
|
".": {
|
|
13
10
|
"types": "./dist/index.d.ts",
|
|
@@ -15,62 +12,50 @@
|
|
|
15
12
|
"require": "./dist/index.js"
|
|
16
13
|
}
|
|
17
14
|
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md",
|
|
18
|
+
"LICENSE"
|
|
19
|
+
],
|
|
20
|
+
"engines": {
|
|
21
|
+
"node": ">=18.0.0"
|
|
22
|
+
},
|
|
18
23
|
"scripts": {
|
|
19
24
|
"build": "tsup",
|
|
20
|
-
"
|
|
21
|
-
"prepublishOnly": "npm run clean && npm run build",
|
|
25
|
+
"dev": "tsup --watch",
|
|
22
26
|
"test": "vitest run",
|
|
23
27
|
"test:watch": "vitest",
|
|
24
28
|
"test:coverage": "vitest run --coverage",
|
|
25
|
-
"lint": "eslint src",
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"format:check": "prettier --check \"src/**/*.ts\"",
|
|
29
|
-
"prepare": "husky"
|
|
29
|
+
"lint": "eslint src --ext .ts",
|
|
30
|
+
"typecheck": "tsc --noEmit",
|
|
31
|
+
"prepublishOnly": "npm run build && npm test"
|
|
30
32
|
},
|
|
31
33
|
"keywords": [
|
|
32
34
|
"waffo",
|
|
33
35
|
"payment",
|
|
36
|
+
"psp",
|
|
37
|
+
"subscription",
|
|
34
38
|
"sdk",
|
|
35
|
-
"nodejs",
|
|
36
|
-
"typescript",
|
|
37
39
|
"ewallet",
|
|
38
|
-
"payment-gateway"
|
|
39
|
-
"rsa",
|
|
40
|
-
"api-client"
|
|
40
|
+
"payment-gateway"
|
|
41
41
|
],
|
|
42
|
-
"author": "Waffo <support@waffo.com>
|
|
42
|
+
"author": "Waffo <merchant.support@waffo.com>",
|
|
43
43
|
"license": "MIT",
|
|
44
44
|
"repository": {
|
|
45
45
|
"type": "git",
|
|
46
|
-
"url": "
|
|
46
|
+
"url": "https://github.com/waffo-com/waffo-sdk"
|
|
47
47
|
},
|
|
48
|
+
"homepage": "https://github.com/waffo-com/waffo-sdk/tree/main/packages/waffo-node",
|
|
48
49
|
"bugs": {
|
|
49
|
-
"url": "https://github.com/waffo-com/waffo-
|
|
50
|
-
},
|
|
51
|
-
"homepage": "https://github.com/waffo-com/waffo-node#readme",
|
|
52
|
-
"engines": {
|
|
53
|
-
"node": ">=18.0.0"
|
|
54
|
-
},
|
|
55
|
-
"lint-staged": {
|
|
56
|
-
"src/**/*.ts": [
|
|
57
|
-
"eslint --fix",
|
|
58
|
-
"prettier --write"
|
|
59
|
-
]
|
|
50
|
+
"url": "https://github.com/waffo-com/waffo-sdk/issues"
|
|
60
51
|
},
|
|
61
52
|
"devDependencies": {
|
|
62
|
-
"@
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"eslint
|
|
67
|
-
"eslint-plugin
|
|
68
|
-
"
|
|
69
|
-
"lint-staged": "^16.2.7",
|
|
70
|
-
"prettier": "^3.7.4",
|
|
71
|
-
"tsup": "^8.5.1",
|
|
72
|
-
"typescript": "^5.9.3",
|
|
73
|
-
"typescript-eslint": "^8.50.1",
|
|
74
|
-
"vitest": "^2.1.8"
|
|
53
|
+
"@types/node": "^20.0.0",
|
|
54
|
+
"typescript": "^5.3.0",
|
|
55
|
+
"tsup": "^8.0.0",
|
|
56
|
+
"vitest": "^1.0.0",
|
|
57
|
+
"eslint": "^8.56.0",
|
|
58
|
+
"@typescript-eslint/eslint-plugin": "^6.19.0",
|
|
59
|
+
"@typescript-eslint/parser": "^6.19.0"
|
|
75
60
|
}
|
|
76
61
|
}
|
package/README.ja.md
DELETED
|
@@ -1,588 +0,0 @@
|
|
|
1
|
-
# Waffo Node.js SDK
|
|
2
|
-
|
|
3
|
-
[](https://www.npmjs.com/package/@waffo/waffo-node)
|
|
4
|
-
[](https://www.npmjs.com/package/@waffo/waffo-node)
|
|
5
|
-
[](https://github.com/AcquireNow/waffo-node/blob/main/LICENSE)
|
|
6
|
-
[](https://www.typescriptlang.org/)
|
|
7
|
-
[](https://nodejs.org/)
|
|
8
|
-
|
|
9
|
-
Waffo アクワイアリングサービスの公式Node.js SDKです。このSDKは、RSA署名によるセキュアなAPI通信と、決済アクワイアリング操作のための包括的な型定義を提供します。
|
|
10
|
-
|
|
11
|
-
**npm**: https://www.npmjs.com/package/@waffo/waffo-node
|
|
12
|
-
|
|
13
|
-
**言語**: [English](./README.md) | [中文](./README.zh-CN.md) | [日本語](./README.ja.md)
|
|
14
|
-
|
|
15
|
-
## クイックスタート
|
|
16
|
-
|
|
17
|
-
```typescript
|
|
18
|
-
import {
|
|
19
|
-
Waffo,
|
|
20
|
-
Environment,
|
|
21
|
-
CurrencyCode,
|
|
22
|
-
ProductName,
|
|
23
|
-
} from '@waffo/waffo-node';
|
|
24
|
-
|
|
25
|
-
// 1. SDKを初期化
|
|
26
|
-
const waffo = new Waffo({
|
|
27
|
-
apiKey: 'your-api-key',
|
|
28
|
-
privateKey: 'your-base64-encoded-private-key',
|
|
29
|
-
environment: Environment.SANDBOX,
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
// 2. 注文を作成
|
|
33
|
-
const result = await waffo.order.create({
|
|
34
|
-
paymentRequestId: 'REQ_001',
|
|
35
|
-
merchantOrderId: 'ORDER_001',
|
|
36
|
-
orderCurrency: CurrencyCode.IDR,
|
|
37
|
-
orderAmount: '100000',
|
|
38
|
-
orderDescription: '商品購入',
|
|
39
|
-
notifyUrl: 'https://merchant.com/notify',
|
|
40
|
-
merchantInfo: { merchantId: 'your-merchant-id' },
|
|
41
|
-
userInfo: {
|
|
42
|
-
userId: 'user_001',
|
|
43
|
-
userEmail: 'user@example.com',
|
|
44
|
-
},
|
|
45
|
-
paymentInfo: {
|
|
46
|
-
productName: ProductName.ONE_TIME_PAYMENT,
|
|
47
|
-
payMethodType: 'EWALLET',
|
|
48
|
-
payMethodName: 'DANA',
|
|
49
|
-
},
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
// 3. レスポンスを処理
|
|
53
|
-
if (result.success) {
|
|
54
|
-
console.log('注文作成成功:', result.data);
|
|
55
|
-
// ユーザーを決済ページにリダイレクト
|
|
56
|
-
if (result.data?.orderAction) {
|
|
57
|
-
const action = JSON.parse(result.data.orderAction);
|
|
58
|
-
window.location.href = action.webUrl;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
> **ヒント**:新しいRSAキーペアが必要ですか?`Waffo.generateKeyPair()` で作成できます:
|
|
64
|
-
> ```typescript
|
|
65
|
-
> const keyPair = Waffo.generateKeyPair();
|
|
66
|
-
> console.log(keyPair.privateKey); // 安全に保管し、SDK初期化に使用
|
|
67
|
-
> console.log(keyPair.publicKey); // Waffoに共有
|
|
68
|
-
> ```
|
|
69
|
-
|
|
70
|
-
## 特徴
|
|
71
|
-
|
|
72
|
-
- RSA-2048によるリクエスト署名とレスポンス検証
|
|
73
|
-
- TypeScriptの完全な型定義サポート
|
|
74
|
-
- 本番環境での依存関係ゼロ(Node.js組み込みの`crypto`モジュールのみ使用)
|
|
75
|
-
- サンドボックス環境と本番環境のサポート
|
|
76
|
-
- デュアルモジュール形式サポート(ESM/CommonJS)
|
|
77
|
-
- 注文管理(作成、照会、キャンセル、返金、キャプチャ)
|
|
78
|
-
- サブスクリプション管理(作成、照会、キャンセル、管理URL取得)
|
|
79
|
-
- 返金ステータス照会
|
|
80
|
-
- 加盟店設定照会(取引限度額、日次限度額)
|
|
81
|
-
- 決済方法設定照会(利用可否、メンテナンス期間)
|
|
82
|
-
- 自動署名検証とイベントルーティングを備えたWebhookハンドラー
|
|
83
|
-
- Webhook署名検証ユーティリティ
|
|
84
|
-
- カスタムAPIリクエスト用の直接HTTPクライアントアクセス
|
|
85
|
-
- リクエストタイムスタンプパラメータの自動デフォルト値
|
|
86
|
-
|
|
87
|
-
## タイムスタンプパラメータの自動デフォルト値
|
|
88
|
-
|
|
89
|
-
すべてのタイムスタンプパラメータ(`orderRequestedAt`、`requestedAt`、`captureRequestedAt`)は**オプション**であり、指定しない場合は自動的に現在時刻(`new Date().toISOString()`)が設定されます:
|
|
90
|
-
|
|
91
|
-
```typescript
|
|
92
|
-
// タイムスタンプは自動的に現在時刻に設定
|
|
93
|
-
await waffo.order.create({
|
|
94
|
-
paymentRequestId: 'REQ_001',
|
|
95
|
-
merchantOrderId: 'ORDER_001',
|
|
96
|
-
// ... その他の必須フィールド
|
|
97
|
-
// orderRequestedAt は自動設定
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
// または明示的にカスタムタイムスタンプを指定
|
|
101
|
-
await waffo.order.create({
|
|
102
|
-
paymentRequestId: 'REQ_001',
|
|
103
|
-
merchantOrderId: 'ORDER_001',
|
|
104
|
-
orderRequestedAt: '2025-01-01T00:00:00.000Z', // カスタムタイムスタンプ
|
|
105
|
-
// ... その他の必須フィールド
|
|
106
|
-
});
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
この機能は以下に適用されます:
|
|
110
|
-
- `CreateOrderParams.orderRequestedAt`
|
|
111
|
-
- `CancelOrderParams.orderRequestedAt`
|
|
112
|
-
- `RefundOrderParams.requestedAt`
|
|
113
|
-
- `CaptureOrderParams.captureRequestedAt`
|
|
114
|
-
- `CreateSubscriptionParams.requestedAt`
|
|
115
|
-
- `CancelSubscriptionParams.requestedAt`
|
|
116
|
-
|
|
117
|
-
## インストール
|
|
118
|
-
|
|
119
|
-
```bash
|
|
120
|
-
npm install @waffo/waffo-node
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
## 使用方法
|
|
124
|
-
|
|
125
|
-
### SDKの初期化
|
|
126
|
-
|
|
127
|
-
```typescript
|
|
128
|
-
import { Waffo, Environment } from '@waffo/waffo-node';
|
|
129
|
-
|
|
130
|
-
const waffo = new Waffo({
|
|
131
|
-
apiKey: 'your-api-key',
|
|
132
|
-
privateKey: 'your-base64-encoded-private-key',
|
|
133
|
-
environment: Environment.SANDBOX, // または Environment.PRODUCTION
|
|
134
|
-
});
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### RSAキーペアの生成
|
|
138
|
-
|
|
139
|
-
```typescript
|
|
140
|
-
import { Waffo } from '@waffo/waffo-node';
|
|
141
|
-
|
|
142
|
-
const keyPair = Waffo.generateKeyPair();
|
|
143
|
-
console.log(keyPair.privateKey); // Base64エンコードされたPKCS8秘密鍵
|
|
144
|
-
console.log(keyPair.publicKey); // Base64エンコードされたX509公開鍵
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
### 注文の作成
|
|
148
|
-
|
|
149
|
-
```typescript
|
|
150
|
-
const result = await waffo.order.create({
|
|
151
|
-
paymentRequestId: 'REQ_001',
|
|
152
|
-
merchantOrderId: 'ORDER_001',
|
|
153
|
-
orderCurrency: CurrencyCode.IDR,
|
|
154
|
-
orderAmount: '100000',
|
|
155
|
-
orderDescription: '商品購入',
|
|
156
|
-
notifyUrl: 'https://merchant.com/notify',
|
|
157
|
-
merchantInfo: {
|
|
158
|
-
merchantId: 'your-merchant-id',
|
|
159
|
-
},
|
|
160
|
-
userInfo: {
|
|
161
|
-
userId: 'user_001',
|
|
162
|
-
userEmail: 'user@example.com',
|
|
163
|
-
userPhone: '+62-81234567890',
|
|
164
|
-
userTerminal: UserTerminalType.WEB,
|
|
165
|
-
},
|
|
166
|
-
paymentInfo: {
|
|
167
|
-
productName: ProductName.ONE_TIME_PAYMENT,
|
|
168
|
-
payMethodType: 'EWALLET',
|
|
169
|
-
payMethodName: 'DANA',
|
|
170
|
-
},
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
if (result.success) {
|
|
174
|
-
console.log('注文作成成功:', result.data);
|
|
175
|
-
} else {
|
|
176
|
-
console.error('エラー:', result.error);
|
|
177
|
-
}
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
### 注文ステータスの照会
|
|
181
|
-
|
|
182
|
-
```typescript
|
|
183
|
-
const result = await waffo.order.inquiry({
|
|
184
|
-
acquiringOrderId: 'A202512230000001',
|
|
185
|
-
// または paymentRequestId: 'REQ_001' を使用
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
if (result.success) {
|
|
189
|
-
console.log('注文ステータス:', result.data?.orderStatus);
|
|
190
|
-
}
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
### 注文のキャンセル
|
|
194
|
-
|
|
195
|
-
```typescript
|
|
196
|
-
const result = await waffo.order.cancel({
|
|
197
|
-
acquiringOrderId: 'A202512230000001',
|
|
198
|
-
merchantId: 'your-merchant-id',
|
|
199
|
-
// orderRequestedAt はオプション、デフォルトは現在時刻
|
|
200
|
-
});
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
### 注文の返金
|
|
204
|
-
|
|
205
|
-
```typescript
|
|
206
|
-
const result = await waffo.order.refund({
|
|
207
|
-
refundRequestId: 'REFUND_001',
|
|
208
|
-
acquiringOrderId: 'A202512230000001',
|
|
209
|
-
merchantId: 'your-merchant-id',
|
|
210
|
-
refundAmount: '50000',
|
|
211
|
-
refundReason: 'お客様からの返金リクエスト',
|
|
212
|
-
refundNotifyUrl: 'https://merchant.com/refund-notify',
|
|
213
|
-
// requestedAt はオプション、デフォルトは現在時刻
|
|
214
|
-
});
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
### 返金ステータスの照会
|
|
218
|
-
|
|
219
|
-
```typescript
|
|
220
|
-
const result = await waffo.refund.inquiry({
|
|
221
|
-
refundRequestId: 'REFUND_001',
|
|
222
|
-
// または acquiringRefundOrderId: 'R202512230000001' を使用
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
if (result.success) {
|
|
226
|
-
console.log('返金ステータス:', result.data?.refundStatus);
|
|
227
|
-
}
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
### 事前承認済み決済のキャプチャ
|
|
231
|
-
|
|
232
|
-
```typescript
|
|
233
|
-
const result = await waffo.order.capture({
|
|
234
|
-
acquiringOrderId: 'A202512230000001',
|
|
235
|
-
merchantId: 'your-merchant-id',
|
|
236
|
-
captureAmount: '100000',
|
|
237
|
-
// captureRequestedAt はオプション、デフォルトは現在時刻
|
|
238
|
-
});
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
### サブスクリプションの作成
|
|
242
|
-
|
|
243
|
-
```typescript
|
|
244
|
-
const result = await waffo.subscription.create({
|
|
245
|
-
subscriptionRequest: 'SUB_REQ_001',
|
|
246
|
-
merchantSubscriptionId: 'MERCHANT_SUB_001',
|
|
247
|
-
currency: CurrencyCode.PHP,
|
|
248
|
-
amount: '100',
|
|
249
|
-
productInfo: {
|
|
250
|
-
periodType: PeriodType.MONTHLY,
|
|
251
|
-
periodInterval: '1',
|
|
252
|
-
numberOfPeriod: '12',
|
|
253
|
-
description: '月額サブスクリプション',
|
|
254
|
-
},
|
|
255
|
-
paymentInfo: {
|
|
256
|
-
productName: ProductName.SUBSCRIPTION,
|
|
257
|
-
payMethodType: 'EWALLET',
|
|
258
|
-
payMethodName: 'GCASH',
|
|
259
|
-
},
|
|
260
|
-
merchantInfo: { merchantId: 'your-merchant-id' },
|
|
261
|
-
userInfo: {
|
|
262
|
-
userId: 'user_001',
|
|
263
|
-
userEmail: 'user@example.com',
|
|
264
|
-
},
|
|
265
|
-
goodsInfo: {
|
|
266
|
-
goodsId: 'GOODS_001',
|
|
267
|
-
goodsName: 'プレミアムプラン',
|
|
268
|
-
},
|
|
269
|
-
notifyUrl: 'https://merchant.com/subscription/notify',
|
|
270
|
-
// requestedAt はオプション、デフォルトは現在時刻
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
if (result.success) {
|
|
274
|
-
console.log('サブスクリプション作成成功:', result.data);
|
|
275
|
-
// ユーザーをサブスクリプション契約完了ページにリダイレクト
|
|
276
|
-
if (result.data?.subscriptionAction?.webUrl) {
|
|
277
|
-
window.location.href = result.data.subscriptionAction.webUrl;
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
### サブスクリプションステータスの照会
|
|
283
|
-
|
|
284
|
-
```typescript
|
|
285
|
-
const result = await waffo.subscription.inquiry({
|
|
286
|
-
merchantId: 'your-merchant-id',
|
|
287
|
-
subscriptionId: 'SUB_202512230000001',
|
|
288
|
-
paymentDetails: '1', // 支払い履歴を含める
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
if (result.success) {
|
|
292
|
-
console.log('サブスクリプションステータス:', result.data?.subscriptionStatus);
|
|
293
|
-
}
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
### サブスクリプションのキャンセル
|
|
297
|
-
|
|
298
|
-
```typescript
|
|
299
|
-
const result = await waffo.subscription.cancel({
|
|
300
|
-
merchantId: 'your-merchant-id',
|
|
301
|
-
subscriptionId: 'SUB_202512230000001',
|
|
302
|
-
// requestedAt はオプション、デフォルトは現在時刻
|
|
303
|
-
});
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
### サブスクリプション管理URLの取得
|
|
307
|
-
|
|
308
|
-
```typescript
|
|
309
|
-
const result = await waffo.subscription.manage({
|
|
310
|
-
subscriptionId: 'SUB_202512230000001',
|
|
311
|
-
// または subscriptionRequest: 'SUB_REQ_001' を使用
|
|
312
|
-
});
|
|
313
|
-
|
|
314
|
-
if (result.success) {
|
|
315
|
-
console.log('管理URL:', result.data?.managementUrl);
|
|
316
|
-
console.log('有効期限:', result.data?.expiresAt);
|
|
317
|
-
// ユーザーをサブスクリプション管理ページにリダイレクト
|
|
318
|
-
window.location.href = result.data?.managementUrl;
|
|
319
|
-
}
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
### 加盟店設定の照会
|
|
323
|
-
|
|
324
|
-
```typescript
|
|
325
|
-
const result = await waffo.merchantConfig.inquiry({
|
|
326
|
-
merchantId: 'your-merchant-id',
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
if (result.success) {
|
|
330
|
-
console.log('日次限度額:', result.data?.totalDailyLimit);
|
|
331
|
-
console.log('残り日次限度額:', result.data?.remainingDailyLimit);
|
|
332
|
-
console.log('取引限度額:', result.data?.transactionLimit);
|
|
333
|
-
}
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
### 決済方法設定の照会
|
|
337
|
-
|
|
338
|
-
```typescript
|
|
339
|
-
const result = await waffo.payMethodConfig.inquiry({
|
|
340
|
-
merchantId: 'your-merchant-id',
|
|
341
|
-
});
|
|
342
|
-
|
|
343
|
-
if (result.success) {
|
|
344
|
-
result.data?.payMethodDetails.forEach(method => {
|
|
345
|
-
console.log(`${method.payMethodName}: ${method.currentStatus === '1' ? '利用可能' : '利用不可'}`);
|
|
346
|
-
if (method.fixedMaintenanceRules) {
|
|
347
|
-
console.log('メンテナンス期間:', method.fixedMaintenanceRules);
|
|
348
|
-
}
|
|
349
|
-
});
|
|
350
|
-
}
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
### Webhookハンドラー
|
|
354
|
-
|
|
355
|
-
SDKには、署名検証、イベントルーティング、レスポンス署名を自動的に処理する組み込みのWebhookハンドラーが用意されています:
|
|
356
|
-
|
|
357
|
-
```typescript
|
|
358
|
-
// Webhookハンドラー内で
|
|
359
|
-
app.post('/webhook', async (req, res) => {
|
|
360
|
-
const signature = req.headers['x-signature'] as string;
|
|
361
|
-
const body = JSON.stringify(req.body);
|
|
362
|
-
|
|
363
|
-
const result = await waffo.webhook.handle(body, signature, {
|
|
364
|
-
onPayment: async ({ notification }) => {
|
|
365
|
-
console.log('支払いステータス:', notification.result.orderStatus);
|
|
366
|
-
// 支払い通知を処理
|
|
367
|
-
},
|
|
368
|
-
onRefund: async ({ notification }) => {
|
|
369
|
-
console.log('返金ステータス:', notification.result.refundStatus);
|
|
370
|
-
// 返金通知を処理
|
|
371
|
-
},
|
|
372
|
-
onSubscriptionStatus: async ({ notification }) => {
|
|
373
|
-
console.log('サブスクリプションステータス:', notification.result.subscriptionStatus);
|
|
374
|
-
// サブスクリプションステータス変更を処理
|
|
375
|
-
},
|
|
376
|
-
onSubscriptionPayment: async ({ notification }) => {
|
|
377
|
-
console.log('サブスクリプション決済:', notification.result.orderStatus);
|
|
378
|
-
// サブスクリプション定期決済を処理
|
|
379
|
-
},
|
|
380
|
-
onError: async (error) => {
|
|
381
|
-
console.error('Webhookエラー:', error.message);
|
|
382
|
-
},
|
|
383
|
-
});
|
|
384
|
-
|
|
385
|
-
return res.json(result.response);
|
|
386
|
-
});
|
|
387
|
-
```
|
|
388
|
-
|
|
389
|
-
### 手動Webhook署名検証
|
|
390
|
-
|
|
391
|
-
より細かい制御が必要な場合は、低レベルのWebhookユーティリティを使用できます:
|
|
392
|
-
|
|
393
|
-
```typescript
|
|
394
|
-
import {
|
|
395
|
-
verifyWebhookSignature,
|
|
396
|
-
buildSuccessResponse,
|
|
397
|
-
buildFailedResponse,
|
|
398
|
-
isPaymentNotification,
|
|
399
|
-
isRefundNotification,
|
|
400
|
-
} from '@waffo/waffo-node';
|
|
401
|
-
|
|
402
|
-
// Webhookハンドラー内で
|
|
403
|
-
app.post('/webhook', (req, res) => {
|
|
404
|
-
const signature = req.headers['x-signature'];
|
|
405
|
-
const body = JSON.stringify(req.body);
|
|
406
|
-
|
|
407
|
-
// 署名を検証
|
|
408
|
-
const verifyResult = verifyWebhookSignature(body, signature, waffoPublicKey);
|
|
409
|
-
|
|
410
|
-
if (!verifyResult.valid) {
|
|
411
|
-
return res.json(buildFailedResponse('署名検証に失敗しました', merchantPrivateKey));
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
// 通知タイプに応じて処理
|
|
415
|
-
const notification = verifyResult.notification;
|
|
416
|
-
|
|
417
|
-
if (isPaymentNotification(notification)) {
|
|
418
|
-
// 支払い通知を処理
|
|
419
|
-
console.log('支払いステータス:', notification.result.orderStatus);
|
|
420
|
-
} else if (isRefundNotification(notification)) {
|
|
421
|
-
// 返金通知を処理
|
|
422
|
-
console.log('返金ステータス:', notification.result.refundStatus);
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
// 成功レスポンスを返す
|
|
426
|
-
return res.json(buildSuccessResponse(merchantPrivateKey));
|
|
427
|
-
});
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
### 直接HTTPクライアントアクセス
|
|
431
|
-
|
|
432
|
-
SDKメソッドでカバーされていないカスタムAPIリクエスト用:
|
|
433
|
-
|
|
434
|
-
```typescript
|
|
435
|
-
const response = await waffo.httpClient.post<CustomResponseType>('/custom/endpoint', {
|
|
436
|
-
body: { key: 'value' }
|
|
437
|
-
});
|
|
438
|
-
|
|
439
|
-
if (response.success) {
|
|
440
|
-
console.log(response.data);
|
|
441
|
-
}
|
|
442
|
-
```
|
|
443
|
-
|
|
444
|
-
## 設定オプション
|
|
445
|
-
|
|
446
|
-
| オプション | 型 | 必須 | デフォルト | 説明 |
|
|
447
|
-
|-----------|------|------|----------|------|
|
|
448
|
-
| `apiKey` | string | はい | - | Waffoから提供されるAPIキー |
|
|
449
|
-
| `privateKey` | string | はい | - | Base64エンコードされたPKCS8秘密鍵 |
|
|
450
|
-
| `waffoPublicKey` | string | いいえ | 組み込み公開鍵 | レスポンス検証用のカスタムWaffo公開鍵 |
|
|
451
|
-
| `environment` | Environment | いいえ | PRODUCTION | API環境(SANDBOXまたはPRODUCTION) |
|
|
452
|
-
| `timeout` | number | いいえ | 30000 | リクエストタイムアウト(ミリ秒) |
|
|
453
|
-
| `logger` | Logger | いいえ | - | デバッグ用のロガーインスタンス(`console`も使用可能) |
|
|
454
|
-
|
|
455
|
-
## APIレスポンス形式
|
|
456
|
-
|
|
457
|
-
すべてのAPIメソッドは`ApiResponse<T>`オブジェクトを返します:
|
|
458
|
-
|
|
459
|
-
```typescript
|
|
460
|
-
interface ApiResponse<T> {
|
|
461
|
-
success: boolean; // リクエストが成功したかどうか
|
|
462
|
-
statusCode: number; // HTTPステータスコード
|
|
463
|
-
data?: T; // レスポンスデータ(成功時)
|
|
464
|
-
error?: string; // エラーメッセージ(失敗時)
|
|
465
|
-
}
|
|
466
|
-
```
|
|
467
|
-
|
|
468
|
-
## 型定義
|
|
469
|
-
|
|
470
|
-
SDKは包括的なTypeScript型定義をエクスポートします:
|
|
471
|
-
|
|
472
|
-
- `Environment` - SDK環境列挙型
|
|
473
|
-
- `CountryCode` - ISO 3166-1 alpha-3国コード
|
|
474
|
-
- `CurrencyCode` - ISO 4217通貨コード
|
|
475
|
-
- `ProductName` - 決済商品タイプ列挙型(ONE_TIME_PAYMENT、SUBSCRIPTION)
|
|
476
|
-
- `payMethodType` - 決済方法カテゴリ(文字列: "EWALLET"、"CREDITCARD"、"BANKTRANSFER"、"ONLINE_BANKING"、"DIGITAL_BANKING"、"OTC"、"DEBITCARD")
|
|
477
|
-
- `payMethodName` - 具体的な決済方法(文字列: "OVO"、"DANA"、"GOPAY"、"GCASH"、"CC_VISA"、"CC_MASTERCARD"、"VA_BCA"、"VA_BNI" など)
|
|
478
|
-
- `OrderStatus` - 注文ステータス列挙型(PAY_IN_PROGRESS、AUTHORIZATION_REQUIRED、PAY_SUCCESS、ORDER_CLOSE など)
|
|
479
|
-
- `RefundStatus` - 返金ステータス列挙型(REFUND_IN_PROGRESS、ORDER_PARTIALLY_REFUNDED、ORDER_FULLY_REFUNDED、ORDER_REFUND_FAILED)
|
|
480
|
-
- `SubscriptionStatus` - サブスクリプションステータス列挙型(AUTHORIZATION_REQUIRED、ACTIVE、PAUSED、MERCHANT_CANCELLED など)
|
|
481
|
-
- `PeriodType` - サブスクリプション期間タイプ列挙型(DAILY、WEEKLY、MONTHLY、YEARLY)
|
|
482
|
-
- `UserTerminalType` - ユーザー端末タイプ列挙型(WEB、APP、IN_WALLET_APP、IN_MINI_PROGRAM)
|
|
483
|
-
- すべてのAPI操作のリクエスト/レスポンスインターフェース
|
|
484
|
-
|
|
485
|
-
## 開発
|
|
486
|
-
|
|
487
|
-
```bash
|
|
488
|
-
# 依存関係のインストール
|
|
489
|
-
npm install
|
|
490
|
-
|
|
491
|
-
# ビルド(ESMとCJSの両方を生成)
|
|
492
|
-
npm run build
|
|
493
|
-
|
|
494
|
-
# テストの実行
|
|
495
|
-
npm test
|
|
496
|
-
|
|
497
|
-
# カバレッジレポート付きテストの実行
|
|
498
|
-
npm run test:coverage
|
|
499
|
-
|
|
500
|
-
# ウォッチモードでテストを実行
|
|
501
|
-
npm run test:watch
|
|
502
|
-
|
|
503
|
-
# コードの静的解析
|
|
504
|
-
npm run lint
|
|
505
|
-
|
|
506
|
-
# コードの静的解析と自動修正
|
|
507
|
-
npm run lint:fix
|
|
508
|
-
|
|
509
|
-
# コードのフォーマット
|
|
510
|
-
npm run format
|
|
511
|
-
|
|
512
|
-
# フォーマットのチェック
|
|
513
|
-
npm run format:check
|
|
514
|
-
```
|
|
515
|
-
|
|
516
|
-
### コード品質
|
|
517
|
-
|
|
518
|
-
このプロジェクトでは以下のツールを使用しています:
|
|
519
|
-
- **ESLint** - TypeScript対応のコード静的解析
|
|
520
|
-
- **Prettier** - コードフォーマッター
|
|
521
|
-
- **Husky** - Gitフック
|
|
522
|
-
- **lint-staged** - ステージされたファイルに対するリンター実行
|
|
523
|
-
|
|
524
|
-
コミット時に、pre-commitフックがステージされた `.ts` ファイルに対してESLintとPrettierを自動的に実行します。
|
|
525
|
-
|
|
526
|
-
### E2Eテストの実行
|
|
527
|
-
|
|
528
|
-
E2Eテストには Waffo サンドボックス環境の認証情報が必要です。SDKは異なるテストシナリオ用に複数の加盟店設定をサポートし、公式のWaffoテストケースドキュメントに基づいた包括的なテストカバレッジを提供します。
|
|
529
|
-
|
|
530
|
-
```bash
|
|
531
|
-
# テンプレートをコピーして認証情報を入力
|
|
532
|
-
cp .env.template .env
|
|
533
|
-
# .env ファイルを編集して認証情報を入力
|
|
534
|
-
```
|
|
535
|
-
|
|
536
|
-
環境変数:
|
|
537
|
-
|
|
538
|
-
| 変数名 | 必須 | 説明 |
|
|
539
|
-
|--------|------|------|
|
|
540
|
-
| `WAFFO_PUBLIC_KEY` | いいえ | 署名検証用のWaffo公開鍵(共通) |
|
|
541
|
-
| `ACQUIRING_MERCHANT_ID` | はい* | 決済/注文テスト用の加盟店ID |
|
|
542
|
-
| `ACQUIRING_API_KEY` | はい* | 決済/注文テスト用のAPIキー |
|
|
543
|
-
| `ACQUIRING_MERCHANT_PRIVATE_KEY` | はい* | 決済/注文テスト用の秘密鍵 |
|
|
544
|
-
| `SUBSCRIPTION_MERCHANT_ID` | はい** | サブスクリプションテスト用の加盟店ID |
|
|
545
|
-
| `SUBSCRIPTION_API_KEY` | はい** | サブスクリプションテスト用のAPIキー |
|
|
546
|
-
| `SUBSCRIPTION_MERCHANT_PRIVATE_KEY` | はい** | サブスクリプションテスト用の秘密鍵 |
|
|
547
|
-
|
|
548
|
-
\* 決済/注文E2Eテストの実行に必要
|
|
549
|
-
\** サブスクリプションE2Eテストの実行に必要
|
|
550
|
-
|
|
551
|
-
**E2Eテストカバレッジ:**
|
|
552
|
-
|
|
553
|
-
| モジュール | テストケース |
|
|
554
|
-
|------------|--------------|
|
|
555
|
-
| 注文作成 | 決済成功/失敗、チャネル拒否 (C0005)、冪等性エラー (A0011)、システムエラー (C0001)、不明ステータス (E0001) |
|
|
556
|
-
| 注文照会 | 決済前/決済後の照会 |
|
|
557
|
-
| 注文キャンセル | 決済前キャンセル、チャネル非対応 (A0015)、決済済み (A0013) |
|
|
558
|
-
| 返金注文 | 全額/部分返金、パラメータ検証 (A0003)、返金ルール (A0014) |
|
|
559
|
-
| サブスクリプション作成 | サブスクリプション成功/失敗、次期決済シミュレーション |
|
|
560
|
-
| サブスクリプションキャンセル | 加盟店起動キャンセル |
|
|
561
|
-
| Webhook通知 | 決済、返金、サブスクリプション通知の署名検証 |
|
|
562
|
-
|
|
563
|
-
**サンドボックス金額トリガールール:**
|
|
564
|
-
|
|
565
|
-
| 金額パターン | エラーコード | 説明 |
|
|
566
|
-
|--------------|--------------|------|
|
|
567
|
-
| 9, 90, 990, 1990, 19990 | C0005 | チャネル拒否 |
|
|
568
|
-
| 9.1, 91, 991, 1991, 19991 | C0001 | システムエラー |
|
|
569
|
-
| 9.2, 92, 992, 1992, 19992 | E0001 | 不明ステータス |
|
|
570
|
-
| 9.3, 93, 993, 1993, 19993 | C0001 | キャンセルシステムエラー |
|
|
571
|
-
| 9.4, 94, 994, 1994, 19994 | E0001 | キャンセル不明ステータス |
|
|
572
|
-
| 9.5, 95, 995, 1995, 19995 | C0001 | 返金システムエラー |
|
|
573
|
-
| 9.6, 96, 996, 1996, 199996 | E0001 | 返金不明ステータス |
|
|
574
|
-
|
|
575
|
-
```bash
|
|
576
|
-
# すべてのテストを実行
|
|
577
|
-
npm test
|
|
578
|
-
```
|
|
579
|
-
|
|
580
|
-
## ビルド出力
|
|
581
|
-
|
|
582
|
-
SDKは [tsup](https://tsup.egoist.dev/) でビルドされ、以下のファイルを出力します:
|
|
583
|
-
|
|
584
|
-
| ファイル | 形式 | 説明 |
|
|
585
|
-
|---------|------|------|
|
|
586
|
-
| `dist/index.js` | CommonJS | `require()` インポート用 |
|
|
587
|
-
| `dist/index.mjs` | ESM | `import` 文用 |
|
|
588
|
-
| `dist/index.d.ts` | TypeScript | 型宣言ファイル |
|