cybersource-brunei-payauth 0.1.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/.claude/scheduled_tasks.lock +1 -0
- package/.gitattributes +2 -0
- package/README.md +76 -0
- package/docs/superpowers/plans/2026-08-10-cybersource-brunei-payer-auth.md +1575 -0
- package/docs/superpowers/specs/2026-08-10-cybersource-brunei-payer-auth-design.md +79 -0
- package/docs/superpowers/specs/2026-08-11-cybersource-tokenization-design.md +229 -0
- package/index.js +4 -0
- package/package.json +13 -0
- package/src/client.js +18 -0
- package/src/errors.js +11 -0
- package/src/httpClient.js +77 -0
- package/src/httpSignature.js +37 -0
- package/src/payerAuth.js +92 -0
- package/src/payments.js +54 -0
- package/src/stepUpForm.js +36 -0
- package/test/client.test.js +56 -0
- package/test/errors.test.js +25 -0
- package/test/httpClient.test.js +157 -0
- package/test/httpSignature.test.js +89 -0
- package/test/index.test.js +23 -0
- package/test/integration.test.js +90 -0
- package/test/payerAuth.test.js +233 -0
- package/test/payments.test.js +175 -0
- package/test/stepUpForm.test.js +69 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"sessionId":"34c2077e-ca7a-48eb-a633-d43df7e24854","pid":23436,"procStart":"134308217849349133","acquiredAt":1786419693310}
|
package/.gitattributes
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# cybersource-brunei-payauth
|
|
2
|
+
|
|
3
|
+
Cybersource REST API client for card payments with EMV 3-D Secure payer authentication, including issuer step-up (OTP) redirect handling for Brunei-issued cards. Hand-rolled HTTP Signature auth — no Cybersource SDK dependency.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
Copy this package into your project (or publish it to your own npm registry) — it has zero runtime dependencies.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
const { createCyberSourceClient, CyberSourceApiError } = require('cybersource-brunei-payauth');
|
|
13
|
+
|
|
14
|
+
const client = createCyberSourceClient({
|
|
15
|
+
merchantId: process.env.CYBERSOURCE_MERCHANT_ID,
|
|
16
|
+
apiKeyId: process.env.CYBERSOURCE_API_KEY_ID,
|
|
17
|
+
apiKeySecret: process.env.CYBERSOURCE_API_KEY_SECRET,
|
|
18
|
+
environment: 'sandbox', // or 'production'
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
async function main() {
|
|
22
|
+
// Illustrative placeholder values — replace with real order/customer data.
|
|
23
|
+
const card = { number: '4111111111111111', type: '001', expirationMonth: '12', expirationYear: '2030' };
|
|
24
|
+
const orderAmount = { currency: 'BND', totalAmount: '50.00' };
|
|
25
|
+
const billTo = {
|
|
26
|
+
firstName: 'Jane', lastName: 'Doe',
|
|
27
|
+
address1: 'Jalan Kianggeh', locality: 'Bandar Seri Begawan',
|
|
28
|
+
administrativeArea: 'BM', postalCode: 'BS8811', country: 'BN',
|
|
29
|
+
email: 'jane@example.com', phoneNumber: '2234567',
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// 1. Setup
|
|
33
|
+
const setup = await client.setupPayerAuth({ card });
|
|
34
|
+
|
|
35
|
+
// 2. Enrollment check
|
|
36
|
+
const enrollment = await client.checkEnrollment({
|
|
37
|
+
referenceId: setup.referenceId,
|
|
38
|
+
card,
|
|
39
|
+
orderAmount,
|
|
40
|
+
returnUrl: 'https://your-site.example/payer-auth-return',
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// authenticationResult ends up populated either directly by checkEnrollment (frictionless
|
|
44
|
+
// pass) or, after a step-up challenge, by validateStepUp.
|
|
45
|
+
let authenticationResult = enrollment.authenticationResult;
|
|
46
|
+
|
|
47
|
+
if (enrollment.stepUpRequired) {
|
|
48
|
+
// 3. Serve this HTML — the customer is redirected to their bank's OTP page
|
|
49
|
+
const html = client.buildStepUpFormHtml(enrollment.stepUp);
|
|
50
|
+
// ... respond with `html` from your route handler here ...
|
|
51
|
+
|
|
52
|
+
// 4. Your /payer-auth-return route receives the bank's POST-back (TransactionId, MD)
|
|
53
|
+
const transactionId = /* req.body.TransactionId from your return-URL route handler */ undefined;
|
|
54
|
+
const validation = await client.validateStepUp({
|
|
55
|
+
transactionId,
|
|
56
|
+
veresEnrolled: enrollment.stepUp.veresEnrolled,
|
|
57
|
+
card,
|
|
58
|
+
orderAmount,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
if (!validation.authenticationResult) {
|
|
62
|
+
// validation.failureReason explains why (e.g. wrong OTP) — ask for another payment method
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
authenticationResult = validation.authenticationResult;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// 5. Authorize (authenticationResult comes from checkEnrollment or validateStepUp)
|
|
69
|
+
const payment = await client.authorize({ card, orderAmount, billTo, authenticationResult });
|
|
70
|
+
|
|
71
|
+
// 6. Capture
|
|
72
|
+
const captured = await client.capture(payment.id, { currency: 'BND', totalAmount: '50.00' });
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
`CyberSourceApiError` is thrown only for transport/HTTP-level failures (bad signature, network error, malformed response). Business outcomes (declined payment, failed OTP) are returned normally — check `status`/`authenticationResult`/`failureReason` on the resolved value.
|