@paykit-sdk/medusajs 1.0.12 → 1.2.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.
- package/README.md +1 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +272 -255
- package/dist/index.mjs +273 -256
- package/dist/providers/paykit-provider.d.mts +20 -15
- package/dist/providers/paykit-provider.d.ts +20 -15
- package/dist/providers/paykit-provider.js +272 -255
- package/dist/providers/paykit-provider.mjs +273 -256
- package/dist/utils/mapper.d.mts +5 -2
- package/dist/utils/mapper.d.ts +5 -2
- package/dist/utils/mapper.js +2 -2
- package/dist/utils/mapper.mjs +2 -2
- package/package.json +5 -2
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ModuleProvider, Modules, AbstractPaymentProvider, MedusaError, PaymentSessionStatus, PaymentActions } from '@medusajs/framework/utils';
|
|
2
|
-
import { providerSchema, PayKit, billingSchema,
|
|
2
|
+
import { providerSchema, PayKit, tryCatchAsync, isIdCustomer, isEmailCustomer, parseCustomerName, billingSchema, PAYKIT_METADATA_KEY, validateRequiredKeys, getURLFromHeaders } from '@paykit-sdk/core';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
|
|
5
5
|
// src/index.ts
|
|
6
|
-
var
|
|
6
|
+
var PaymentStatus$inboundSchema = (status) => {
|
|
7
7
|
switch (status) {
|
|
8
8
|
case "pending":
|
|
9
9
|
case "processing":
|
|
@@ -27,51 +27,80 @@ var medusaStatus$InboundSchema = (status) => {
|
|
|
27
27
|
var optionsSchema = z.object({
|
|
28
28
|
/**
|
|
29
29
|
* The underlying PayKit provider instance (Stripe, PayPal, etc.)
|
|
30
|
-
* This is required and must be a valid PayKit provider instance
|
|
31
30
|
*/
|
|
32
31
|
provider: providerSchema,
|
|
33
32
|
/**
|
|
34
|
-
* The webhook secret for the provider
|
|
35
|
-
* This is required and must be a valid webhook secret
|
|
33
|
+
* The webhook secret for the provider.
|
|
36
34
|
*/
|
|
37
|
-
webhookSecret: z.string(),
|
|
35
|
+
webhookSecret: z.string().nullable().default(null),
|
|
36
|
+
/**
|
|
37
|
+
* Multiplier applied to the amount before sending to the payment provider.
|
|
38
|
+
* Use this when your provider expects amounts in the smallest currency unit (e.g. cents)
|
|
39
|
+
* but Medusa is passing amounts in the major unit (e.g. euros).
|
|
40
|
+
*/
|
|
41
|
+
amountToCentsMultiplier: z.number().min(1).default(1),
|
|
38
42
|
/**
|
|
39
43
|
* Whether to enable debug mode
|
|
40
|
-
* If enabled, the adapter will log debug information to the console
|
|
41
44
|
*/
|
|
42
45
|
debug: z.boolean().optional()
|
|
43
46
|
});
|
|
44
|
-
var PaykitMedusaJSAdapter = class extends AbstractPaymentProvider {
|
|
47
|
+
var PaykitMedusaJSAdapter = class _PaykitMedusaJSAdapter extends AbstractPaymentProvider {
|
|
45
48
|
/**
|
|
46
49
|
* The unique identifier for this payment provider
|
|
47
50
|
* Will be stored as `pp_paykit_{id}` in Medusa
|
|
48
51
|
*/
|
|
49
52
|
static identifier = "paykit";
|
|
53
|
+
static adapterMetadata = {
|
|
54
|
+
name: "medusajs",
|
|
55
|
+
version: "1.2.0"
|
|
56
|
+
};
|
|
50
57
|
paykit;
|
|
51
|
-
provider;
|
|
52
58
|
options;
|
|
53
59
|
static validateOptions(options) {
|
|
54
60
|
const { error } = optionsSchema.safeParse(options);
|
|
55
61
|
if (error) {
|
|
56
|
-
throw new MedusaError(
|
|
62
|
+
throw new MedusaError(
|
|
63
|
+
MedusaError.Types.INVALID_DATA,
|
|
64
|
+
error.message
|
|
65
|
+
);
|
|
57
66
|
}
|
|
58
67
|
return;
|
|
59
68
|
}
|
|
60
69
|
/**
|
|
61
|
-
* Constructor receives Medusa's container and provider options
|
|
62
|
-
*
|
|
63
70
|
* @param cradle - Medusa's dependency injection container
|
|
64
71
|
* @param options - PayKit provider configuration
|
|
65
72
|
*/
|
|
66
73
|
constructor(cradle, options) {
|
|
67
74
|
super(cradle, options);
|
|
68
75
|
this.options = options;
|
|
69
|
-
this.
|
|
70
|
-
|
|
76
|
+
this.paykit = new PayKit(
|
|
77
|
+
options.provider,
|
|
78
|
+
_PaykitMedusaJSAdapter.adapterMetadata
|
|
79
|
+
);
|
|
71
80
|
if (this.options.debug) {
|
|
72
|
-
console.info(
|
|
81
|
+
console.info(
|
|
82
|
+
`[PayKit] Initialized with provider: ${this.paykit.providerName}`
|
|
83
|
+
);
|
|
73
84
|
}
|
|
74
85
|
}
|
|
86
|
+
async exec(promise, context, options) {
|
|
87
|
+
const [result, error] = await tryCatchAsync(promise);
|
|
88
|
+
if (error) {
|
|
89
|
+
if (options?.allowUnsupported && error.name === "ProviderNotSupportedError") {
|
|
90
|
+
if (this.options.debug) {
|
|
91
|
+
console.warn(
|
|
92
|
+
`[PayKit ${context}] Operation not supported by ${this.paykit.providerName}.`
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
throw new MedusaError(
|
|
98
|
+
MedusaError.Types.PAYMENT_AUTHORIZATION_ERROR,
|
|
99
|
+
`[PayKit ${context}] ${error.message}`
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
return result;
|
|
103
|
+
}
|
|
75
104
|
initiatePayment = async ({
|
|
76
105
|
context,
|
|
77
106
|
amount,
|
|
@@ -81,341 +110,338 @@ var PaykitMedusaJSAdapter = class extends AbstractPaymentProvider {
|
|
|
81
110
|
if (this.options.debug) {
|
|
82
111
|
console.info("[PayKit] Initiating payment", {
|
|
83
112
|
context,
|
|
84
|
-
amount,
|
|
113
|
+
amount: Number(amount) * this.options.amountToCentsMultiplier,
|
|
85
114
|
currency_code,
|
|
86
115
|
data
|
|
87
116
|
});
|
|
88
117
|
}
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
currency: currency_code,
|
|
92
|
-
metadata: { ...data?.metadata ?? {}, session_id: data?.session_id ?? null },
|
|
93
|
-
provider_metadata: data?.provider_metadata,
|
|
94
|
-
capture_method: "manual",
|
|
95
|
-
item_id: data?.item_id
|
|
96
|
-
};
|
|
97
|
-
let customer;
|
|
118
|
+
const hasProviderCustomer = !!context?.account_holder?.data?.id;
|
|
119
|
+
let customer = null;
|
|
98
120
|
if (context?.account_holder?.data?.id) {
|
|
99
|
-
customer = context.account_holder.data.id;
|
|
100
|
-
}
|
|
101
|
-
|
|
121
|
+
customer = { id: context.account_holder.data.id };
|
|
122
|
+
} else if (context?.customer?.email) {
|
|
123
|
+
customer = { email: context.customer.email };
|
|
124
|
+
} else if (data?.email) {
|
|
102
125
|
customer = { email: data.email };
|
|
103
126
|
}
|
|
104
|
-
if (!customer) {
|
|
105
|
-
throw new MedusaError(
|
|
106
|
-
MedusaError.Types.INVALID_DATA,
|
|
107
|
-
"Required: customer ID (account_holder) or email (data)"
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
const billingInfoParsed = billingSchema.safeParse(data?.billing);
|
|
111
|
-
if (data?.billing && !billingInfoParsed.success) {
|
|
127
|
+
if (!customer || !isIdCustomer(customer) && !isEmailCustomer(customer)) {
|
|
112
128
|
throw new MedusaError(
|
|
113
129
|
MedusaError.Types.INVALID_DATA,
|
|
114
|
-
|
|
130
|
+
"Customer ID (account_holder) or Email (context.customer or data.email) required"
|
|
115
131
|
);
|
|
116
132
|
}
|
|
117
|
-
if (
|
|
118
|
-
const
|
|
119
|
-
|
|
133
|
+
if (!hasProviderCustomer && isEmailCustomer(customer)) {
|
|
134
|
+
const { fullName } = parseCustomerName({
|
|
135
|
+
name: `${context?.customer?.first_name ?? ""} ${context?.customer?.last_name ?? ""}`.trim(),
|
|
136
|
+
email: customer.email
|
|
137
|
+
});
|
|
138
|
+
const billingInfo = billingSchema.safeParse(data?.billing);
|
|
139
|
+
if (data?.billing && !billingInfo.success) {
|
|
140
|
+
throw new MedusaError(
|
|
141
|
+
MedusaError.Types.INVALID_DATA,
|
|
142
|
+
`Invalid billing information, ${billingInfo.error.message} `
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
const created = await this.exec(
|
|
120
146
|
this.paykit.customers.create({
|
|
121
147
|
email: customer.email,
|
|
122
|
-
|
|
123
|
-
|
|
148
|
+
name: fullName,
|
|
149
|
+
phone: data?.phone ?? null,
|
|
150
|
+
billing: billingInfo.data ?? null,
|
|
124
151
|
metadata: {
|
|
125
|
-
PAYKIT_METADATA_KEY: JSON.stringify({
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
})
|
|
129
|
-
);
|
|
130
|
-
if (createError) {
|
|
131
|
-
if (createError.name === "ProviderNotSupportedError") {
|
|
132
|
-
if (this.options.debug) {
|
|
133
|
-
console.info(
|
|
134
|
-
`[PayKit] Provider ${this.provider.providerName} doesn't support customer creation, using email object`
|
|
135
|
-
);
|
|
152
|
+
[PAYKIT_METADATA_KEY]: JSON.stringify({
|
|
153
|
+
source: "medusa-paykit-adapter"
|
|
154
|
+
})
|
|
136
155
|
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
156
|
+
}),
|
|
157
|
+
"Customer Creation",
|
|
158
|
+
{ allowUnsupported: true }
|
|
159
|
+
);
|
|
160
|
+
if (created) {
|
|
161
|
+
customer = {
|
|
162
|
+
..."id" in created ? { id: created.id } : {},
|
|
163
|
+
..."email" in created ? { email: created.email } : {}
|
|
164
|
+
};
|
|
145
165
|
}
|
|
146
|
-
} else {
|
|
147
|
-
customer = customer;
|
|
148
166
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
167
|
+
const payment = await this.exec(
|
|
168
|
+
this.paykit.payments.create({
|
|
169
|
+
amount: Number(amount) * this.options.amountToCentsMultiplier,
|
|
170
|
+
currency: currency_code.toUpperCase(),
|
|
171
|
+
customer,
|
|
172
|
+
item_id: data?.item_id ?? null,
|
|
173
|
+
capture_method: "manual",
|
|
174
|
+
metadata: {
|
|
175
|
+
...data?.metadata,
|
|
176
|
+
session_id: data?.session_id
|
|
177
|
+
},
|
|
178
|
+
...data?.billing ? { billing: data.billing } : {},
|
|
179
|
+
provider_metadata: data?.provider_metadata
|
|
180
|
+
}),
|
|
181
|
+
"Initiate"
|
|
152
182
|
);
|
|
153
|
-
if (paymentIntentError) {
|
|
154
|
-
throw new MedusaError(
|
|
155
|
-
MedusaError.Types.PAYMENT_AUTHORIZATION_ERROR,
|
|
156
|
-
paymentIntentError.message
|
|
157
|
-
);
|
|
158
|
-
}
|
|
159
|
-
if (paymentIntentResult.requires_action && paymentIntentResult.payment_url) {
|
|
160
|
-
return {
|
|
161
|
-
id: paymentIntentResult.id,
|
|
162
|
-
status: PaymentSessionStatus.REQUIRES_MORE,
|
|
163
|
-
data: {
|
|
164
|
-
payment_url: paymentIntentResult.payment_url
|
|
165
|
-
}
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
183
|
return {
|
|
169
|
-
id:
|
|
170
|
-
status:
|
|
184
|
+
id: payment.id,
|
|
185
|
+
status: payment.requires_action ? PaymentSessionStatus.REQUIRES_MORE : PaymentStatus$inboundSchema(payment.status),
|
|
186
|
+
data: { ...payment, payment_url: payment.payment_url }
|
|
171
187
|
};
|
|
172
188
|
};
|
|
173
189
|
capturePayment = async (input) => {
|
|
174
190
|
if (this.options.debug) {
|
|
175
191
|
console.info("[PayKit] Capturing payment", input);
|
|
176
192
|
}
|
|
177
|
-
const { id, amount } = validateRequiredKeys(
|
|
193
|
+
const { id: paymentId, amount } = validateRequiredKeys(
|
|
178
194
|
["id", "amount"],
|
|
179
|
-
input
|
|
195
|
+
input.data ?? {},
|
|
180
196
|
"Missing required fields: {keys}",
|
|
181
197
|
(message) => new MedusaError(MedusaError.Types.INVALID_DATA, message)
|
|
182
198
|
);
|
|
183
|
-
const
|
|
184
|
-
this.paykit.payments.capture(
|
|
199
|
+
const data = await this.exec(
|
|
200
|
+
this.paykit.payments.capture(paymentId, {
|
|
201
|
+
amount: Number(amount) * this.options.amountToCentsMultiplier
|
|
202
|
+
}),
|
|
203
|
+
"Capture"
|
|
185
204
|
);
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
paymentIntentError.message
|
|
190
|
-
);
|
|
191
|
-
return { data: paymentIntentResult };
|
|
205
|
+
return {
|
|
206
|
+
data
|
|
207
|
+
};
|
|
192
208
|
};
|
|
193
209
|
authorizePayment = async (input) => {
|
|
194
|
-
|
|
195
|
-
|
|
210
|
+
const { id: paymentId } = validateRequiredKeys(
|
|
211
|
+
["id"],
|
|
212
|
+
input.data ?? {},
|
|
213
|
+
"Missing required fields: {keys}",
|
|
214
|
+
(message) => new MedusaError(MedusaError.Types.INVALID_DATA, message)
|
|
215
|
+
);
|
|
216
|
+
const payment = await this.exec(
|
|
217
|
+
this.paykit.payments.retrieve(paymentId),
|
|
218
|
+
"Authorize"
|
|
219
|
+
);
|
|
220
|
+
if (!payment) {
|
|
221
|
+
throw new MedusaError(
|
|
222
|
+
MedusaError.Types.NOT_FOUND,
|
|
223
|
+
"Payment not found"
|
|
224
|
+
);
|
|
196
225
|
}
|
|
197
|
-
|
|
226
|
+
const resolvedStatus = (() => {
|
|
227
|
+
if (payment.requires_action)
|
|
228
|
+
return PaymentSessionStatus.REQUIRES_MORE;
|
|
229
|
+
if (payment.status === "succeeded")
|
|
230
|
+
return PaymentSessionStatus.AUTHORIZED;
|
|
231
|
+
return PaymentStatus$inboundSchema(payment.status);
|
|
232
|
+
})();
|
|
233
|
+
return {
|
|
234
|
+
status: resolvedStatus,
|
|
235
|
+
data: payment
|
|
236
|
+
};
|
|
198
237
|
};
|
|
199
238
|
cancelPayment = async (input) => {
|
|
200
239
|
if (this.options.debug) {
|
|
201
240
|
console.info("[PayKit] Canceling payment", input);
|
|
202
241
|
}
|
|
203
|
-
const { id } = validateRequiredKeys(
|
|
242
|
+
const { id: paymentId } = validateRequiredKeys(
|
|
204
243
|
["id"],
|
|
205
|
-
input
|
|
244
|
+
input.data ?? {},
|
|
206
245
|
"Missing required fields: {keys}",
|
|
207
246
|
(message) => new MedusaError(MedusaError.Types.INVALID_DATA, message)
|
|
208
247
|
);
|
|
209
|
-
const
|
|
210
|
-
this.paykit.payments.cancel(
|
|
248
|
+
const data = await this.exec(
|
|
249
|
+
this.paykit.payments.cancel(paymentId),
|
|
250
|
+
"Cancel"
|
|
211
251
|
);
|
|
212
|
-
|
|
213
|
-
throw new MedusaError(
|
|
214
|
-
MedusaError.Types.PAYMENT_AUTHORIZATION_ERROR,
|
|
215
|
-
paymentIntentError.message
|
|
216
|
-
);
|
|
217
|
-
return { data: paymentIntentResult };
|
|
252
|
+
return { data };
|
|
218
253
|
};
|
|
219
254
|
deletePayment = async (input) => {
|
|
220
|
-
|
|
255
|
+
if (this.options.debug) {
|
|
256
|
+
console.info(
|
|
257
|
+
"[PayKit] Deleting payment (attempting cancel)",
|
|
258
|
+
input
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
const paymentId = input.data?.id;
|
|
262
|
+
if (!paymentId) {
|
|
263
|
+
return {};
|
|
264
|
+
}
|
|
265
|
+
const data = await this.exec(
|
|
266
|
+
this.paykit.payments.cancel(paymentId),
|
|
267
|
+
"Cancel",
|
|
268
|
+
{ allowUnsupported: true }
|
|
269
|
+
);
|
|
270
|
+
return { data };
|
|
221
271
|
};
|
|
222
272
|
getPaymentStatus = async (input) => {
|
|
223
|
-
const { id } = validateRequiredKeys(
|
|
273
|
+
const { id: paymentId } = validateRequiredKeys(
|
|
224
274
|
["id"],
|
|
225
|
-
input
|
|
275
|
+
input.data ?? {},
|
|
226
276
|
"Missing required fields: {keys}",
|
|
227
277
|
(message) => new MedusaError(MedusaError.Types.INVALID_DATA, message)
|
|
228
278
|
);
|
|
229
|
-
const
|
|
230
|
-
this.paykit.payments.retrieve(
|
|
279
|
+
const payment = await this.exec(
|
|
280
|
+
this.paykit.payments.retrieve(paymentId),
|
|
281
|
+
"Status"
|
|
231
282
|
);
|
|
232
|
-
if (
|
|
283
|
+
if (!payment)
|
|
233
284
|
throw new MedusaError(
|
|
234
|
-
MedusaError.Types.
|
|
235
|
-
paymentIntentError.message
|
|
236
|
-
);
|
|
237
|
-
if (!paymentIntentResult)
|
|
238
|
-
throw new MedusaError(
|
|
239
|
-
MedusaError.Types.PAYMENT_AUTHORIZATION_ERROR,
|
|
285
|
+
MedusaError.Types.NOT_FOUND,
|
|
240
286
|
"Payment not found"
|
|
241
287
|
);
|
|
242
288
|
return {
|
|
243
|
-
status:
|
|
244
|
-
data:
|
|
289
|
+
status: PaymentStatus$inboundSchema(payment.status),
|
|
290
|
+
data: payment
|
|
245
291
|
};
|
|
246
292
|
};
|
|
247
293
|
refundPayment = async (input) => {
|
|
248
294
|
if (this.options.debug) {
|
|
249
295
|
console.info("[PayKit] Refunding payment", input);
|
|
250
296
|
}
|
|
251
|
-
const { id: paymentId } = validateRequiredKeys(
|
|
252
|
-
["id"],
|
|
253
|
-
input
|
|
297
|
+
const { id: paymentId, reason = "customer_request" } = validateRequiredKeys(
|
|
298
|
+
["id", "reason"],
|
|
299
|
+
input.data ?? {},
|
|
254
300
|
"Missing required fields: {keys}",
|
|
255
301
|
(message) => new MedusaError(MedusaError.Types.INVALID_DATA, message)
|
|
256
302
|
);
|
|
257
|
-
const
|
|
303
|
+
const refund = await this.exec(
|
|
258
304
|
this.paykit.refunds.create({
|
|
259
305
|
payment_id: paymentId,
|
|
260
|
-
amount: Number(input.amount),
|
|
261
|
-
reason
|
|
262
|
-
metadata: input.data?.metadata
|
|
263
|
-
provider_metadata: input.data?.provider_metadata
|
|
264
|
-
})
|
|
306
|
+
amount: Number(input.amount) * this.options.amountToCentsMultiplier,
|
|
307
|
+
reason,
|
|
308
|
+
metadata: input.data?.metadata ?? null,
|
|
309
|
+
provider_metadata: input.data?.provider_metadata ?? void 0
|
|
310
|
+
}),
|
|
311
|
+
"Refund"
|
|
265
312
|
);
|
|
266
|
-
|
|
267
|
-
throw new MedusaError(
|
|
268
|
-
MedusaError.Types.PAYMENT_AUTHORIZATION_ERROR,
|
|
269
|
-
refundError.message
|
|
270
|
-
);
|
|
271
|
-
return { data: refundResult };
|
|
313
|
+
return { data: refund };
|
|
272
314
|
};
|
|
273
315
|
retrievePayment = async (input) => {
|
|
274
316
|
if (this.options.debug) {
|
|
275
317
|
console.info("[PayKit] Retrieving payment", input);
|
|
276
318
|
}
|
|
277
|
-
const { id } = validateRequiredKeys(
|
|
319
|
+
const { id: paymentId } = validateRequiredKeys(
|
|
278
320
|
["id"],
|
|
279
|
-
input
|
|
321
|
+
input.data ?? {},
|
|
280
322
|
"Missing required fields: {keys}",
|
|
281
323
|
(message) => new MedusaError(MedusaError.Types.INVALID_DATA, message)
|
|
282
324
|
);
|
|
283
|
-
const
|
|
284
|
-
this.paykit.payments.retrieve(
|
|
325
|
+
const payment = await this.exec(
|
|
326
|
+
this.paykit.payments.retrieve(paymentId),
|
|
327
|
+
"Retrieve"
|
|
285
328
|
);
|
|
286
|
-
|
|
287
|
-
throw new MedusaError(
|
|
288
|
-
MedusaError.Types.PAYMENT_AUTHORIZATION_ERROR,
|
|
289
|
-
paymentIntentError.message
|
|
290
|
-
);
|
|
291
|
-
return { data: paymentIntentResult };
|
|
329
|
+
return { data: payment };
|
|
292
330
|
};
|
|
293
331
|
updatePayment = async (input) => {
|
|
294
332
|
if (this.options.debug) {
|
|
295
333
|
console.info("[PayKit] Updating payment", input);
|
|
296
334
|
}
|
|
297
|
-
const {
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
["id"],
|
|
305
|
-
input.data,
|
|
335
|
+
const {
|
|
336
|
+
amount,
|
|
337
|
+
id: paymentId,
|
|
338
|
+
currency_code: currencyCode
|
|
339
|
+
} = validateRequiredKeys(
|
|
340
|
+
["amount", "currency_code", "id"],
|
|
341
|
+
input.data ?? {},
|
|
306
342
|
"Missing required fields: {keys}",
|
|
307
343
|
(message) => new MedusaError(MedusaError.Types.INVALID_DATA, message)
|
|
308
344
|
);
|
|
309
|
-
const
|
|
310
|
-
const [paymentIntentResult, paymentIntentError] = await tryCatchAsync(
|
|
345
|
+
const data = await this.exec(
|
|
311
346
|
this.paykit.payments.update(paymentId, {
|
|
312
|
-
amount: Number(amount),
|
|
313
|
-
currency:
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
347
|
+
amount: Number(amount) * this.options.amountToCentsMultiplier,
|
|
348
|
+
currency: currencyCode.toUpperCase(),
|
|
349
|
+
provider_metadata: input.data?.provider_metadata
|
|
350
|
+
}),
|
|
351
|
+
"Update"
|
|
317
352
|
);
|
|
318
|
-
|
|
319
|
-
throw new MedusaError(
|
|
320
|
-
MedusaError.Types.PAYMENT_AUTHORIZATION_ERROR,
|
|
321
|
-
paymentIntentError.message
|
|
322
|
-
);
|
|
323
|
-
return { data: paymentIntentResult };
|
|
353
|
+
return { data };
|
|
324
354
|
};
|
|
325
355
|
getWebhookActionAndData = async (payload) => {
|
|
326
356
|
if (this.options.debug) {
|
|
327
|
-
console.info(
|
|
357
|
+
console.info(
|
|
358
|
+
"[PayKit] Resolving webhook action and data",
|
|
359
|
+
payload
|
|
360
|
+
);
|
|
328
361
|
}
|
|
329
362
|
const { rawData, headers } = payload;
|
|
330
|
-
const
|
|
363
|
+
const body = Buffer.isBuffer(rawData) ? rawData.toString("utf8") : rawData;
|
|
364
|
+
const headersMap = Object.fromEntries(
|
|
365
|
+
Object.entries(headers).map(([k, v]) => [k, String(v)])
|
|
366
|
+
);
|
|
367
|
+
let result = {
|
|
368
|
+
action: PaymentActions.NOT_SUPPORTED
|
|
369
|
+
};
|
|
370
|
+
const statusMap = {
|
|
371
|
+
pending: PaymentActions.PENDING,
|
|
372
|
+
processing: PaymentActions.PENDING,
|
|
373
|
+
requires_action: PaymentActions.REQUIRES_MORE,
|
|
374
|
+
requires_capture: PaymentActions.AUTHORIZED,
|
|
375
|
+
succeeded: PaymentActions.SUCCESSFUL,
|
|
376
|
+
failed: PaymentActions.FAILED,
|
|
377
|
+
canceled: PaymentActions.CANCELED
|
|
378
|
+
};
|
|
331
379
|
const webhook = this.paykit.webhooks.setup({ webhookSecret: this.options.webhookSecret }).on("payment.created", async (event) => {
|
|
332
|
-
|
|
333
|
-
action:
|
|
380
|
+
result = {
|
|
381
|
+
action: statusMap[event?.data?.status ?? "pending"],
|
|
334
382
|
data: {
|
|
335
383
|
session_id: event.data?.metadata?.session_id,
|
|
336
|
-
amount: event.data?.amount
|
|
384
|
+
amount: event.data?.amount ? event.data?.amount * this.options.amountToCentsMultiplier : 0
|
|
337
385
|
}
|
|
338
386
|
};
|
|
339
387
|
}).on("payment.updated", async (event) => {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
processing: PaymentActions.PENDING,
|
|
343
|
-
requires_action: PaymentActions.REQUIRES_MORE,
|
|
344
|
-
requires_capture: PaymentActions.AUTHORIZED,
|
|
345
|
-
succeeded: PaymentActions.SUCCESSFUL,
|
|
346
|
-
failed: PaymentActions.FAILED,
|
|
347
|
-
canceled: PaymentActions.CANCELED
|
|
348
|
-
};
|
|
349
|
-
return {
|
|
350
|
-
action: event.data?.status ? statusActionMap[event.data.status] : PaymentActions.PENDING,
|
|
388
|
+
result = {
|
|
389
|
+
action: statusMap[event?.data?.status ?? "pending"],
|
|
351
390
|
data: {
|
|
352
391
|
session_id: event.data?.metadata?.session_id,
|
|
353
|
-
amount: event.data?.amount
|
|
392
|
+
amount: event.data?.amount ? event.data?.amount * this.options.amountToCentsMultiplier : 0
|
|
354
393
|
}
|
|
355
394
|
};
|
|
356
|
-
}).on("payment.
|
|
357
|
-
|
|
395
|
+
}).on("payment.failed", async (event) => {
|
|
396
|
+
result = {
|
|
358
397
|
action: PaymentActions.CANCELED,
|
|
359
398
|
data: {
|
|
360
|
-
|
|
361
|
-
|
|
399
|
+
amount: event.data?.amount ? event.data?.amount * this.options.amountToCentsMultiplier : 0,
|
|
400
|
+
session_id: event.data?.metadata?.session_id
|
|
362
401
|
}
|
|
363
402
|
};
|
|
364
403
|
});
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
body: bodyString,
|
|
370
|
-
headers: new Headers(stringifiedHeaders),
|
|
371
|
-
fullUrl: getURLFromHeaders(stringifiedHeaders)
|
|
404
|
+
await webhook.handle({
|
|
405
|
+
body,
|
|
406
|
+
headersAsObject: headersMap,
|
|
407
|
+
fullUrl: getURLFromHeaders(headersMap)
|
|
372
408
|
});
|
|
373
|
-
return
|
|
409
|
+
return result;
|
|
374
410
|
};
|
|
375
411
|
createAccountHolder = async ({
|
|
376
412
|
context,
|
|
377
413
|
data
|
|
378
414
|
}) => {
|
|
415
|
+
if (context.account_holder?.data?.id) {
|
|
416
|
+
return { id: context.account_holder.data.id };
|
|
417
|
+
}
|
|
379
418
|
if (this.options.debug) {
|
|
380
419
|
console.info("[PayKit] Creating account holder", context, data);
|
|
381
420
|
}
|
|
382
|
-
const {
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
if (!
|
|
387
|
-
throw new MedusaError(
|
|
388
|
-
MedusaError.Types.INVALID_DATA,
|
|
389
|
-
"Customer not found in context"
|
|
390
|
-
);
|
|
391
|
-
}
|
|
392
|
-
const billingInfoParsed = billingSchema.safeParse(data?.billing);
|
|
393
|
-
if (data?.billing && !billingInfoParsed.success) {
|
|
421
|
+
const { fullName } = parseCustomerName({
|
|
422
|
+
email: context.customer?.email
|
|
423
|
+
});
|
|
424
|
+
const billingInfo = billingSchema.safeParse(data?.billing);
|
|
425
|
+
if (data?.billing && !billingInfo.success) {
|
|
394
426
|
throw new MedusaError(
|
|
395
427
|
MedusaError.Types.INVALID_DATA,
|
|
396
|
-
`Invalid billing information, ${
|
|
428
|
+
`Invalid billing information, ${billingInfo.error.message} `
|
|
397
429
|
);
|
|
398
430
|
}
|
|
399
|
-
const
|
|
431
|
+
const res = await this.exec(
|
|
400
432
|
this.paykit.customers.create({
|
|
401
|
-
email: customer
|
|
402
|
-
name:
|
|
403
|
-
phone: customer
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
})
|
|
433
|
+
email: context.customer?.email,
|
|
434
|
+
name: fullName,
|
|
435
|
+
phone: context.customer?.phone ?? null,
|
|
436
|
+
billing: billingInfo.data ?? null
|
|
437
|
+
}),
|
|
438
|
+
"Create Account Holder",
|
|
439
|
+
{ allowUnsupported: true }
|
|
409
440
|
);
|
|
410
|
-
if (
|
|
411
|
-
throw new MedusaError(
|
|
412
|
-
MedusaError.Types.PAYMENT_AUTHORIZATION_ERROR,
|
|
413
|
-
accountHolderError.message
|
|
414
|
-
);
|
|
415
|
-
}
|
|
441
|
+
if (!res) return {};
|
|
416
442
|
return {
|
|
417
|
-
id:
|
|
418
|
-
data:
|
|
443
|
+
id: res.id,
|
|
444
|
+
data: res
|
|
419
445
|
};
|
|
420
446
|
};
|
|
421
447
|
updateAccountHolder = async ({
|
|
@@ -433,27 +459,24 @@ var PaykitMedusaJSAdapter = class extends AbstractPaymentProvider {
|
|
|
433
459
|
);
|
|
434
460
|
}
|
|
435
461
|
if (!customer) return {};
|
|
436
|
-
const
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
...data?.
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
},
|
|
447
|
-
|
|
448
|
-
|
|
462
|
+
const res = await this.exec(
|
|
463
|
+
this.paykit.customers.update(account_holder.data.id, {
|
|
464
|
+
...data?.billing != null ? {
|
|
465
|
+
billing: billingSchema.safeParse(data.billing).data ?? null
|
|
466
|
+
} : {},
|
|
467
|
+
...data?.email != null ? { email: data.email } : {},
|
|
468
|
+
...data?.name != null ? { name: data.name } : {},
|
|
469
|
+
...data?.phone != null ? { phone: data.phone } : {},
|
|
470
|
+
...data?.metadata != null ? {
|
|
471
|
+
metadata: data.metadata
|
|
472
|
+
} : {},
|
|
473
|
+
...data?.provider_metadata != null ? {
|
|
474
|
+
provider_metadata: data.provider_metadata
|
|
475
|
+
} : {}
|
|
476
|
+
}),
|
|
477
|
+
"Update Account Holder"
|
|
449
478
|
);
|
|
450
|
-
|
|
451
|
-
throw new MedusaError(
|
|
452
|
-
MedusaError.Types.PAYMENT_AUTHORIZATION_ERROR,
|
|
453
|
-
accountHolderError.message
|
|
454
|
-
);
|
|
455
|
-
}
|
|
456
|
-
return { data: accountHolderResult };
|
|
479
|
+
return { data: res };
|
|
457
480
|
};
|
|
458
481
|
deleteAccountHolder = async ({
|
|
459
482
|
context,
|
|
@@ -469,17 +492,11 @@ var PaykitMedusaJSAdapter = class extends AbstractPaymentProvider {
|
|
|
469
492
|
"Account holder not found in context"
|
|
470
493
|
);
|
|
471
494
|
}
|
|
472
|
-
const
|
|
473
|
-
|
|
474
|
-
|
|
495
|
+
const res = await this.exec(
|
|
496
|
+
this.paykit.customers.delete(account_holder.data.id),
|
|
497
|
+
"Delete Account Holder"
|
|
475
498
|
);
|
|
476
|
-
|
|
477
|
-
throw new MedusaError(
|
|
478
|
-
MedusaError.Types.PAYMENT_AUTHORIZATION_ERROR,
|
|
479
|
-
accountHolderError.message
|
|
480
|
-
);
|
|
481
|
-
}
|
|
482
|
-
return { data: accountHolderResult };
|
|
499
|
+
return { data: res };
|
|
483
500
|
};
|
|
484
501
|
};
|
|
485
502
|
|