Files
WRNexusJS/packages/payment/test/adapter-contract.test.ts
T
Clintchiz fe44bc2091
Quality / quality (ubuntu-latest) (push) Failing after 9m53s
Quality / quality (windows-latest) (push) Canceled after 0s
fix: make payment event reduction monotonic
2026-08-23 21:34:59 +05:30

238 lines
7.6 KiB
TypeScript

import { afterEach, expect, test } from "bun:test";
import {
exerciseGatewayContract,
paypalGateway,
razorpayGateway,
sandboxGateway,
signSandboxWebhook,
stripeGateway,
type GatewayIntent,
} from "../src/index.ts";
const originalFetch = globalThis.fetch;
afterEach(() => {
globalThis.fetch = originalFetch;
});
const json = (value: unknown, status = 200) =>
new Response(JSON.stringify(value), { status, headers: { "content-type": "application/json" } });
const encoder = new TextEncoder();
async function signature(body: string, secret: string) {
const key = await crypto.subtle.importKey(
"raw",
encoder.encode(secret),
{ name: "HMAC", hash: "SHA-256" },
false,
["sign"],
);
return [...new Uint8Array(await crypto.subtle.sign("HMAC", key, encoder.encode(body)))]
.map((x) => x.toString(16).padStart(2, "0"))
.join("");
}
const input = {
id: "contract-pay",
subject: "contract-user",
amount: 1000,
currency: "USD",
idempotencyKey: "contract-init",
};
test("shared executable contract drives sandbox", async () => {
const adapter = sandboxGateway();
const report = await exerciseGatewayContract(adapter, {
input,
async webhook(intent) {
const signed = await signSandboxWebhook(
{
id: "sb-event",
intentRef: intent.ref,
type: "payment.captured",
status: "captured",
occurredAt: 100,
},
"contract-webhook-secret",
);
return new Request("https://test", {
method: "POST",
headers: { "x-wrnexus-signature": signed.signature },
body: signed.body,
});
},
});
expect(report).toEqual({ ok: true, issues: [] });
});
test("shared executable contract drives Stripe through its HTTP adapter", async () => {
globalThis.fetch = (async (value, init) => {
const url = String(value),
method = init?.method ?? "GET";
if (
url.includes("/payment_intents") &&
method === "POST" &&
!url.endsWith("/capture") &&
!url.endsWith("/cancel")
) {
const body = String(init?.body);
const id = body.includes("cancel") ? "pi_cancel" : "pi_contract";
return json({
id,
status: "requires_capture",
amount: 1000,
amount_received: 1000,
currency: "usd",
client_secret: "pi_client_safe",
});
}
if (url.endsWith("/capture"))
return json({
id: "pi_contract",
status: "succeeded",
amount_received: 1000,
currency: "usd",
});
if (url.endsWith("/cancel"))
return json({ id: "pi_cancel", status: "canceled", amount: 1000, currency: "usd" });
if (url.includes("/payment_intents/"))
return json({ id: "pi_contract", status: "requires_capture", amount: 1000, currency: "usd" });
if (url.endsWith("/refunds")) return json({ id: "re_1", status: "succeeded", amount: 500 });
if (url.endsWith("/customers")) return json({ id: "cus_1" });
if (url.includes("/payment_methods?")) return json({ data: [] });
if (url.includes("/payment_methods/") && url.endsWith("/attach"))
return json({
id: "pm_1",
card: { brand: "visa", last4: "4242", exp_month: 1, exp_year: 2030 },
});
if (url.includes("/payment_methods/") && url.endsWith("/detach")) return json({ id: "pm_1" });
return json({}, 404);
}) as typeof fetch;
const adapter = stripeGateway({
secretKey: "sk_test_secret",
publishableKey: "pk_test",
webhookSecret: "contract-webhook-secret",
});
const report = await exerciseGatewayContract(adapter, {
input,
async webhook(intent) {
const body = JSON.stringify({
id: "evt_1",
created: 100,
data: { object: { id: intent.ref, status: "succeeded" } },
type: "payment_intent.succeeded",
});
return new Request("https://test", {
method: "POST",
headers: {
"stripe-signature": `t=100,v1=${await signature(`100.${body}`, "contract-webhook-secret")}`,
},
body,
});
},
});
expect(report).toEqual({ ok: true, issues: [] });
});
test("shared executable contract drives Razorpay through its HTTP adapter", async () => {
globalThis.fetch = (async (value, init) => {
const url = String(value),
method = init?.method ?? "GET";
if (url.endsWith("/orders") && method === "POST") {
const body = String(init?.body);
return json({
id: body.includes("cancel") ? "order_cancel" : "order_1",
status: "created",
amount: 1000,
currency: "USD",
});
}
if (url.includes("/orders/"))
return json({
id: url.endsWith("order_cancel") ? "order_cancel" : "order_1",
status: "created",
amount: 1000,
currency: "USD",
});
if (url.includes("/refund")) return json({ id: "rfnd_1", status: "processed", amount: 500 });
return json({}, 404);
}) as typeof fetch;
const adapter = razorpayGateway({
keyId: "rzp_test",
keySecret: "key_secret",
webhookSecret: "contract-webhook-secret",
});
const report = await exerciseGatewayContract(adapter, {
input,
async webhook(intent) {
const body = JSON.stringify({
id: "rz_evt",
event: "payment.captured",
payload: {
payment: {
entity: { id: "pay_1", order_id: intent.ref, status: "captured", created_at: 100 },
},
},
});
return new Request("https://test", {
method: "POST",
headers: { "x-razorpay-signature": await signature(body, "contract-webhook-secret") },
body,
});
},
});
expect(report).toEqual({ ok: true, issues: [] });
});
test("shared executable contract drives PayPal through its HTTP adapter", async () => {
globalThis.fetch = (async (value, init) => {
const url = String(value),
method = init?.method ?? "GET";
if (url.endsWith("/oauth2/token")) return json({ access_token: "access" });
if (url.endsWith("/checkout/orders") && method === "POST") {
const body = String(init?.body);
return json({
id: body.includes("cancel") ? "PP-CANCEL" : "PP-ORDER",
status: "CREATED",
links: [{ rel: "approve", href: "https://paypal.test/approve" }],
});
}
if (url.includes("/checkout/orders/"))
return json({
id: url.endsWith("PP-CANCEL") ? "PP-CANCEL" : "PP-ORDER",
status: "CREATED",
purchase_units: [{ amount: { value: "10.00", currency_code: "USD" } }],
});
if (url.includes("/refund")) return json({ id: "PP-REFUND", status: "COMPLETED" });
if (url.endsWith("verify-webhook-signature")) return json({ verification_status: "SUCCESS" });
return json({}, 404);
}) as typeof fetch;
const adapter = paypalGateway({
clientId: "client",
clientSecret: "paypal_secret",
webhookId: "hook",
});
const report = await exerciseGatewayContract(adapter, {
input,
webhook(intent: GatewayIntent) {
return new Request("https://test", {
method: "POST",
headers: {
"paypal-auth-algo": "SHA256withRSA",
"paypal-cert-url": "https://paypal.test/cert",
"paypal-transmission-id": "tx",
"paypal-transmission-sig": "sig",
"paypal-transmission-time": "time",
},
body: JSON.stringify({
id: "WH-1",
create_time: "2026-08-23T00:00:00Z",
event_type: "PAYMENT.CAPTURE.COMPLETED",
resource: {
id: "CAPTURE",
status: "COMPLETED",
supplementary_data: { related_ids: { order_id: intent.ref } },
},
}),
});
},
});
expect(report).toEqual({ ok: true, issues: [] });
});