@queelabs/connectors-stripe 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ import type { MppPaymentAdapter } from "@queelabs/core";
2
+ /**
3
+ * Stripe adapter (MPP-shaped): maps Stripe Checkout sessions
4
+ * to Quee payment challenges and receipts.
5
+ */
6
+ export declare function createStripeMppConnector(): MppPaymentAdapter;
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGV,iBAAiB,EAGlB,MAAM,gBAAgB,CAAC;AAaxB;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,iBAAiB,CAgH5D"}
package/dist/index.js ADDED
@@ -0,0 +1,114 @@
1
+ import Stripe from "stripe";
2
+ function readRecord(source, key) {
3
+ const value = source[key];
4
+ if (!value || typeof value !== "object" || Array.isArray(value))
5
+ return null;
6
+ return value;
7
+ }
8
+ function readString(source, key) {
9
+ const value = source[key];
10
+ return typeof value === "string" && value.length > 0 ? value : null;
11
+ }
12
+ /**
13
+ * Stripe adapter (MPP-shaped): maps Stripe Checkout sessions
14
+ * to Quee payment challenges and receipts.
15
+ */
16
+ export function createStripeMppConnector() {
17
+ return {
18
+ async createPurchaseChallenge(input) {
19
+ const secretKey = process.env.STRIPE_SECRET_KEY;
20
+ if (!secretKey) {
21
+ throw new Error("STRIPE_SECRET_KEY is not set");
22
+ }
23
+ const rawCheckoutBaseUrl = process.env.QUEE_CHECKOUT_BASE_URL;
24
+ if (!rawCheckoutBaseUrl) {
25
+ throw new Error("QUEE_CHECKOUT_BASE_URL is not set");
26
+ }
27
+ const checkoutBaseUrl = rawCheckoutBaseUrl.replace(/\/+$/, "");
28
+ const stripe = new Stripe(secretKey);
29
+ const session = await stripe.checkout.sessions.create({
30
+ payment_method_types: ["card"],
31
+ line_items: [
32
+ {
33
+ price_data: {
34
+ currency: input.currency.toLowerCase(),
35
+ product_data: {
36
+ name: `Order ${input.orderId}`,
37
+ },
38
+ unit_amount: input.amountMinor,
39
+ },
40
+ quantity: 1,
41
+ },
42
+ ],
43
+ mode: "payment",
44
+ success_url: `${checkoutBaseUrl}/pay/${input.orderId}/success`,
45
+ cancel_url: `${checkoutBaseUrl}/pay/${input.orderId}/cancel`,
46
+ metadata: {
47
+ orderId: input.orderId,
48
+ marketplaceId: input.marketplaceId,
49
+ },
50
+ });
51
+ return {
52
+ challengeId: `stripe_ch_${input.orderId}`,
53
+ rail: "stripe",
54
+ payload: {
55
+ type: "stripe_checkout_challenge",
56
+ version: "0.2",
57
+ orderId: input.orderId,
58
+ amountMinor: input.amountMinor,
59
+ currency: input.currency,
60
+ stripe: {
61
+ checkoutUrl: session.url,
62
+ sessionId: session.id,
63
+ publishableKey: process.env.STRIPE_PUBLISHABLE_KEY,
64
+ },
65
+ },
66
+ };
67
+ },
68
+ async verifyPurchase(input) {
69
+ const secretKey = process.env.STRIPE_SECRET_KEY;
70
+ if (!secretKey) {
71
+ throw new Error("STRIPE_SECRET_KEY is not set");
72
+ }
73
+ const stripe = new Stripe(secretKey);
74
+ const expectedSessionId = readString(readRecord(input.challengePayload, "stripe") ?? {}, "sessionId");
75
+ const sessionId = typeof input.proof.stripeSessionId === "string"
76
+ ? input.proof.stripeSessionId
77
+ : null;
78
+ if (!expectedSessionId || !sessionId || sessionId !== expectedSessionId) {
79
+ throw new Error("stripe proof does not match stored challenge");
80
+ }
81
+ const session = await stripe.checkout.sessions.retrieve(sessionId);
82
+ if (session.id !== expectedSessionId) {
83
+ throw new Error("Stripe session does not match stored challenge");
84
+ }
85
+ if (session.payment_status !== "paid") {
86
+ throw new Error(`Stripe session not paid: ${session.payment_status}`);
87
+ }
88
+ if (session.amount_total !== input.expectedAmountMinor) {
89
+ throw new Error("Stripe session amount does not match order");
90
+ }
91
+ if ((session.currency ?? "").toLowerCase() !== input.expectedCurrency.toLowerCase()) {
92
+ throw new Error("Stripe session currency does not match order");
93
+ }
94
+ if (session.metadata?.orderId !== input.orderId) {
95
+ throw new Error("Stripe session orderId metadata does not match order");
96
+ }
97
+ if (session.metadata?.marketplaceId !== input.marketplaceId) {
98
+ throw new Error("Stripe session marketplaceId metadata does not match marketplace");
99
+ }
100
+ return {
101
+ receiptPayload: {
102
+ verified: true,
103
+ challengeId: input.challengeId,
104
+ orderId: input.orderId,
105
+ settledVia: "stripe",
106
+ proof: input.proof,
107
+ providerReference: session.payment_intent,
108
+ },
109
+ verifiedAt: new Date(),
110
+ };
111
+ },
112
+ };
113
+ }
114
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAS5B,SAAS,UAAU,CAAC,MAA+B,EAAE,GAAW;IAC9D,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7E,OAAO,KAAgC,CAAC;AAC1C,CAAC;AAED,SAAS,UAAU,CAAC,MAA+B,EAAE,GAAW;IAC9D,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACtE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,wBAAwB;IACtC,OAAO;QACL,KAAK,CAAC,uBAAuB,CAC3B,KAA2B;YAE3B,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;YAChD,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;YAClD,CAAC;YACD,MAAM,kBAAkB,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC;YAC9D,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBACxB,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;YACvD,CAAC;YACD,MAAM,eAAe,GAAG,kBAAkB,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAE/D,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC;YACrC,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC;gBACpD,oBAAoB,EAAE,CAAC,MAAM,CAAC;gBAC9B,UAAU,EAAE;oBACV;wBACE,UAAU,EAAE;4BACV,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE;4BACtC,YAAY,EAAE;gCACZ,IAAI,EAAE,SAAS,KAAK,CAAC,OAAO,EAAE;6BAC/B;4BACD,WAAW,EAAE,KAAK,CAAC,WAAW;yBAC/B;wBACD,QAAQ,EAAE,CAAC;qBACZ;iBACF;gBACD,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,GAAG,eAAe,QAAQ,KAAK,CAAC,OAAO,UAAU;gBAC9D,UAAU,EAAE,GAAG,eAAe,QAAQ,KAAK,CAAC,OAAO,SAAS;gBAC5D,QAAQ,EAAE;oBACR,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,aAAa,EAAE,KAAK,CAAC,aAAa;iBACnC;aACF,CAAC,CAAC;YAEH,OAAO;gBACL,WAAW,EAAE,aAAa,KAAK,CAAC,OAAO,EAAE;gBACzC,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE;oBACP,IAAI,EAAE,2BAA2B;oBACjC,OAAO,EAAE,KAAK;oBACd,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,WAAW,EAAE,KAAK,CAAC,WAAW;oBAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,MAAM,EAAE;wBACN,WAAW,EAAE,OAAO,CAAC,GAAG;wBACxB,SAAS,EAAE,OAAO,CAAC,EAAE;wBACrB,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB;qBACnD;iBACF;aACF,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,cAAc,CAAC,KAAyB;YAC5C,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;YAChD,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;YAClD,CAAC;YAED,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC;YACrC,MAAM,iBAAiB,GAAG,UAAU,CAClC,UAAU,CAAC,KAAK,CAAC,gBAAgB,EAAE,QAAQ,CAAC,IAAI,EAAE,EAClD,WAAW,CACZ,CAAC;YACF,MAAM,SAAS,GACb,OAAO,KAAK,CAAC,KAAK,CAAC,eAAe,KAAK,QAAQ;gBAC7C,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,eAAe;gBAC7B,CAAC,CAAC,IAAI,CAAC;YACX,IAAI,CAAC,iBAAiB,IAAI,CAAC,SAAS,IAAI,SAAS,KAAK,iBAAiB,EAAE,CAAC;gBACxE,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;YAClE,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YACnE,IAAI,OAAO,CAAC,EAAE,KAAK,iBAAiB,EAAE,CAAC;gBACrC,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;YACpE,CAAC;YAED,IAAI,OAAO,CAAC,cAAc,KAAK,MAAM,EAAE,CAAC;gBACtC,MAAM,IAAI,KAAK,CAAC,4BAA4B,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;YACxE,CAAC;YACD,IAAI,OAAO,CAAC,YAAY,KAAK,KAAK,CAAC,mBAAmB,EAAE,CAAC;gBACvD,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;YAChE,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,gBAAgB,CAAC,WAAW,EAAE,EAAE,CAAC;gBACpF,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;YAClE,CAAC;YACD,IAAI,OAAO,CAAC,QAAQ,EAAE,OAAO,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;gBAChD,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;YAC1E,CAAC;YACD,IAAI,OAAO,CAAC,QAAQ,EAAE,aAAa,KAAK,KAAK,CAAC,aAAa,EAAE,CAAC;gBAC5D,MAAM,IAAI,KAAK,CACb,kEAAkE,CACnE,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,cAAc,EAAE;oBACd,QAAQ,EAAE,IAAI;oBACd,WAAW,EAAE,KAAK,CAAC,WAAW;oBAC9B,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,UAAU,EAAE,QAAQ;oBACpB,KAAK,EAAE,KAAK,CAAC,KAAK;oBAClB,iBAAiB,EAAE,OAAO,CAAC,cAAwB;iBACpD;gBACD,UAAU,EAAE,IAAI,IAAI,EAAE;aACvB,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@queelabs/connectors-stripe",
3
+ "version": "0.0.1",
4
+ "license": "UNLICENSED",
5
+ "description": "Stripe payment connector for Quee",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "publishConfig": {
13
+ "access": "public"
14
+ },
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/quee-protocol/quee.git",
18
+ "directory": "connectors/stripe"
19
+ },
20
+ "exports": {
21
+ ".": {
22
+ "import": "./dist/index.js",
23
+ "types": "./dist/index.d.ts"
24
+ }
25
+ },
26
+ "dependencies": {
27
+ "stripe": "^22.0.1",
28
+ "@queelabs/core": "0.0.1"
29
+ },
30
+ "devDependencies": {
31
+ "@types/node": "^22.10.2",
32
+ "typescript": "^5.7.2"
33
+ },
34
+ "scripts": {
35
+ "build": "tsc",
36
+ "lint": "echo ok"
37
+ }
38
+ }