@henrylabs-interview/payment-processor 0.2.10 → 0.2.11
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 +3 -3
- package/dist/resources/checkout.js +32 -18
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -56,7 +56,7 @@ Operations may:
|
|
|
56
56
|
## Initialize (Backend)
|
|
57
57
|
|
|
58
58
|
```ts
|
|
59
|
-
import { PaymentProcessor } from '
|
|
59
|
+
import { PaymentProcessor } from '@henrylabs-interview/payment-processor';
|
|
60
60
|
|
|
61
61
|
const processor = new PaymentProcessor({
|
|
62
62
|
apiKey: ...,
|
|
@@ -109,7 +109,7 @@ The SDK provides an optional embeddable checkout UI for collecting card details
|
|
|
109
109
|
## Initialize Embedded Checkout
|
|
110
110
|
|
|
111
111
|
```ts
|
|
112
|
-
import { EmbeddedCheckout } from '
|
|
112
|
+
import { EmbeddedCheckout } from '@henrylabs-interview/payment-processor';
|
|
113
113
|
|
|
114
114
|
const embedded = new EmbeddedCheckout({
|
|
115
115
|
checkoutId: 'chk_123',
|
|
@@ -121,7 +121,7 @@ const embedded = new EmbeddedCheckout({
|
|
|
121
121
|
## Render Embedded Checkout
|
|
122
122
|
|
|
123
123
|
```ts
|
|
124
|
-
embedded.render('checkout-container', (paymentToken) => {
|
|
124
|
+
embedded.render('#checkout-container', (paymentToken) => {
|
|
125
125
|
console.log('Received payment token:', paymentToken);
|
|
126
126
|
|
|
127
127
|
// Send token to backend for confirmation
|
|
@@ -142,8 +142,7 @@ export class Checkout {
|
|
|
142
142
|
setTimeout(async () => {
|
|
143
143
|
// Deferred flow resolves later
|
|
144
144
|
if (response.status === 'success' && response.substatus === '202-deferred') {
|
|
145
|
-
|
|
146
|
-
if (isSuccess) {
|
|
145
|
+
if (Math.random() > 0.2) {
|
|
147
146
|
const checkoutId = await this.createCheckoutRecord(hashId);
|
|
148
147
|
this.sendWebhookResponse('checkout.create', {
|
|
149
148
|
status: 'success',
|
|
@@ -156,6 +155,14 @@ export class Checkout {
|
|
|
156
155
|
},
|
|
157
156
|
});
|
|
158
157
|
}
|
|
158
|
+
else if (Math.random() > 0.05) {
|
|
159
|
+
this.sendWebhookResponse('checkout.create', {
|
|
160
|
+
status: 'failure',
|
|
161
|
+
substatus: '503-retry',
|
|
162
|
+
code: 503,
|
|
163
|
+
message: 'Server error, please retry the request',
|
|
164
|
+
});
|
|
165
|
+
}
|
|
159
166
|
else {
|
|
160
167
|
this.sendWebhookResponse('checkout.create', {
|
|
161
168
|
status: 'failure',
|
|
@@ -222,24 +229,24 @@ export class Checkout {
|
|
|
222
229
|
if (!isValidCardNumber(number)) {
|
|
223
230
|
return {
|
|
224
231
|
status: 'failure',
|
|
225
|
-
substatus: '
|
|
226
|
-
code:
|
|
232
|
+
substatus: '500-error',
|
|
233
|
+
code: 500,
|
|
227
234
|
message: 'Invalid card number',
|
|
228
235
|
};
|
|
229
236
|
}
|
|
230
237
|
if (!isValidExpiry(expMonth, expYear)) {
|
|
231
238
|
return {
|
|
232
239
|
status: 'failure',
|
|
233
|
-
substatus: '
|
|
234
|
-
code:
|
|
240
|
+
substatus: '500-error',
|
|
241
|
+
code: 500,
|
|
235
242
|
message: 'Card expired',
|
|
236
243
|
};
|
|
237
244
|
}
|
|
238
245
|
if (!/^\d{3,4}$/.test(cvc)) {
|
|
239
246
|
return {
|
|
240
247
|
status: 'failure',
|
|
241
|
-
substatus: '
|
|
242
|
-
code:
|
|
248
|
+
substatus: '500-error',
|
|
249
|
+
code: 500,
|
|
243
250
|
message: 'Invalid CVC',
|
|
244
251
|
};
|
|
245
252
|
}
|
|
@@ -248,7 +255,7 @@ export class Checkout {
|
|
|
248
255
|
}
|
|
249
256
|
async processConfirmDecision(params) {
|
|
250
257
|
const decision = Math.random();
|
|
251
|
-
if (decision > 0.
|
|
258
|
+
if (decision > 0.95) {
|
|
252
259
|
return {
|
|
253
260
|
status: 'failure',
|
|
254
261
|
substatus: '502-fraud',
|
|
@@ -318,12 +325,19 @@ export class Checkout {
|
|
|
318
325
|
const webhookDelay = Math.random() * 3000;
|
|
319
326
|
setTimeout(() => {
|
|
320
327
|
if (response.status === 'success' && response.substatus === '202-deferred') {
|
|
321
|
-
|
|
322
|
-
if (isSuccess) {
|
|
328
|
+
if (Math.random() > 0.2) {
|
|
323
329
|
this.buildInstantConfirmSuccess(params.checkoutId).then((finalResponse) => {
|
|
324
330
|
this.sendWebhookResponse('checkout.confirm', finalResponse);
|
|
325
331
|
});
|
|
326
332
|
}
|
|
333
|
+
else if (Math.random() > 0.05) {
|
|
334
|
+
this.sendWebhookResponse('checkout.confirm', {
|
|
335
|
+
status: 'failure',
|
|
336
|
+
substatus: '503-retry',
|
|
337
|
+
code: 503,
|
|
338
|
+
message: 'Server error, please retry the request',
|
|
339
|
+
});
|
|
340
|
+
}
|
|
327
341
|
else {
|
|
328
342
|
this.sendWebhookResponse('checkout.confirm', {
|
|
329
343
|
status: 'failure',
|
|
@@ -343,7 +357,7 @@ export class Checkout {
|
|
|
343
357
|
let immediateWeight = 65;
|
|
344
358
|
let deferredWeight = 20;
|
|
345
359
|
let retryWeight = 10;
|
|
346
|
-
let fraudWeight =
|
|
360
|
+
let fraudWeight = 0;
|
|
347
361
|
// --- Adjust based on repeated attempts ---
|
|
348
362
|
immediateWeight -= sameRecords * 10;
|
|
349
363
|
deferredWeight += sameRecords * 5;
|
|
@@ -351,16 +365,16 @@ export class Checkout {
|
|
|
351
365
|
fraudWeight += sameRecords * 5;
|
|
352
366
|
// --- Adjust based on amount ---
|
|
353
367
|
if (amount > 1000) {
|
|
354
|
-
deferredWeight +=
|
|
355
|
-
retryWeight += 5;
|
|
368
|
+
deferredWeight += sameRecords * 5;
|
|
369
|
+
retryWeight += sameRecords * 5;
|
|
356
370
|
}
|
|
357
371
|
if (amount > 5000) {
|
|
358
|
-
immediateWeight -=
|
|
359
|
-
retryWeight +=
|
|
360
|
-
fraudWeight +=
|
|
372
|
+
immediateWeight -= sameRecords * 5;
|
|
373
|
+
retryWeight += sameRecords * 5;
|
|
374
|
+
fraudWeight += sameRecords * 5;
|
|
361
375
|
}
|
|
362
376
|
if (amount > 10000) {
|
|
363
|
-
fraudWeight +=
|
|
377
|
+
fraudWeight += sameRecords * 5;
|
|
364
378
|
}
|
|
365
379
|
// Ensure no negative weights
|
|
366
380
|
immediateWeight = Math.max(0, immediateWeight);
|