@givinglite/react 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/LICENSE +21 -0
- package/README.md +85 -0
- package/dist/helpers.d.ts +49 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +170 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +194 -0
- package/dist/index.js.map +1 -0
- package/dist/stripe.d.ts +24 -0
- package/dist/stripe.d.ts.map +1 -0
- package/dist/stripe.js +36 -0
- package/dist/stripe.js.map +1 -0
- package/dist/styles.d.ts +2 -0
- package/dist/styles.d.ts.map +1 -0
- package/dist/styles.js +11 -0
- package/dist/styles.js.map +1 -0
- package/package.json +40 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 GivingLite
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# @givinglite/react
|
|
2
|
+
|
|
3
|
+
Native React form for one-time Canadian PAD donations through GivingLite. It renders in the host DOM and is designed for a Next.js App Router client component. Stripe.js owns the secure bank-account and mandate modal/frames; the SDK never collects, receives, or stores bank data.
|
|
4
|
+
|
|
5
|
+
> **Pilot release:** Versions below 1.0 are intended for controlled GivingLite pilots. The package currently supports one-time Canadian PAD in Stripe test mode, requires a configured GivingLite backend, and may introduce breaking API changes between minor releases.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm install @givinglite/react
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
React 18 and React 19 are supported as peer dependencies.
|
|
14
|
+
|
|
15
|
+
## Next.js App Router
|
|
16
|
+
|
|
17
|
+
Create a client component. Do not put a private API credential in this component; `apiUrl` is a public browser-visible GivingLite origin.
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
'use client';
|
|
21
|
+
|
|
22
|
+
import { GivingLiteDonationForm } from '@givinglite/react';
|
|
23
|
+
|
|
24
|
+
export function DonationForm() {
|
|
25
|
+
return (
|
|
26
|
+
<GivingLiteDonationForm
|
|
27
|
+
apiUrl="https://api.givinglite.example"
|
|
28
|
+
charitySlug="example-charity"
|
|
29
|
+
formSlug="general"
|
|
30
|
+
branding={{ accentColor: '#155e75', accentTextColor: '#ffffff' }}
|
|
31
|
+
copy={{ title: 'Support our work' }}
|
|
32
|
+
onStarted={({ idempotencyKey }) =>
|
|
33
|
+
console.info('Started', idempotencyKey)
|
|
34
|
+
}
|
|
35
|
+
onComplete={({ status }) => console.info('Complete', status)}
|
|
36
|
+
onError={(error) => console.error(error)}
|
|
37
|
+
/>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`apiUrl`, `charitySlug`, and `formSlug` are the only required props. The SDK automatically loads the published form configuration, including suggested and minimum amounts, custom-amount and cost-coverage policy, charity identity, form copy, and branding. The form shows a loading or error state without donation controls until that authoritative configuration is available.
|
|
43
|
+
|
|
44
|
+
The optional `branding` and `copy` props are presentation-only overlays. They can adjust host-site wording and safe six-digit hex accent colors, but cannot override donation policy. When no accent is supplied, the SDK uses the charity's primary color and derives readable button text. `stripeLoader`, `fetcher`, and lifecycle callbacks remain injectable.
|
|
45
|
+
|
|
46
|
+
All monetary values are integer Canadian cents. Styles are included in the rendered component, use `glr-pad`-prefixed selectors, and do not require Tailwind or host CSS. The API must permit CORS requests from the host site.
|
|
47
|
+
|
|
48
|
+
## API contract
|
|
49
|
+
|
|
50
|
+
The SDK first sends `GET {apiUrl}/api/v1/charities/{charitySlug}/forms/{formSlug}/configuration`, then sends `POST {apiUrl}/api/v1/charities/{charitySlug}/forms/{formSlug}/donations` with an `Idempotency-Key` UUID header and this JSON body:
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"amount": 5000,
|
|
55
|
+
"donor": {
|
|
56
|
+
"firstName": "Ada",
|
|
57
|
+
"lastName": "Lovelace",
|
|
58
|
+
"email": "ada@example.org"
|
|
59
|
+
},
|
|
60
|
+
"campaignId": null,
|
|
61
|
+
"coverCosts": true
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`amount` is the base gift in integer cents. The response must contain `clientSecret`, `publishableKey`, and either a same-origin signed `statusUrl` or `reconciliationUrl`. After Stripe returns a PaymentIntent, the SDK posts to that signed URL without supplying a Stripe identifier; GivingLite reconciles the PaymentIntent already stored for the attempt. The reconciliation response may return `stripeStatus`, `status`, or `paymentStatus`; the Stripe-specific value takes precedence so verification requirements are not hidden by a coarse pending state. Supported results are processing/pending, verification required, succeeded/paid/completed, and failed/canceled/requires payment method. Unknown Stripe statuses are conservatively displayed as processing because Canadian PAD settlement is asynchronous.
|
|
66
|
+
|
|
67
|
+
The server remains authoritative for charity/form availability, amount, cost coverage, PaymentIntent metadata, and final payment status. A browser callback is not proof of settlement.
|
|
68
|
+
|
|
69
|
+
## Content Security Policy
|
|
70
|
+
|
|
71
|
+
Stripe.js is loaded directly from `https://js.stripe.com/v3/`; it is not bundled or proxied. At minimum, account for these sources in the host CSP, along with the configured GivingLite API origin:
|
|
72
|
+
|
|
73
|
+
```text
|
|
74
|
+
script-src https://js.stripe.com
|
|
75
|
+
frame-src https://js.stripe.com https://hooks.stripe.com
|
|
76
|
+
connect-src https://api.stripe.com https://api.givinglite.example
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Merge those origins into the site's existing policy rather than replacing it. Stripe may require additional regional/payment-method origins; follow Stripe's current CSP documentation. Stripe still uses its own secure modal/frames to collect bank details and mandate acceptance.
|
|
80
|
+
|
|
81
|
+
## Testing
|
|
82
|
+
|
|
83
|
+
`stripeLoader` and `fetcher` can be injected for component integration tests. Pure URL, configuration, request, color, and status helpers are exported for unit testing. Importing the package is SSR-safe, while rendering and Stripe confirmation must happen in a client component.
|
|
84
|
+
|
|
85
|
+
The package currently keeps its test runtime dependency-free, so configuration-fetch lifecycle behavior does not have an automated DOM test. Manually verify loading, failed configuration, identity changes, hidden custom amounts, and cost-coverage defaults when integrating the component in a browser.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export type DonationStatus = 'processing' | 'verification-required' | 'succeeded' | 'failed';
|
|
2
|
+
export interface DonationRequest {
|
|
3
|
+
amount: number;
|
|
4
|
+
donor: {
|
|
5
|
+
firstName: string;
|
|
6
|
+
lastName: string;
|
|
7
|
+
email: string;
|
|
8
|
+
};
|
|
9
|
+
campaignId: null;
|
|
10
|
+
coverCosts: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface DonationStartResponse {
|
|
13
|
+
clientSecret: string;
|
|
14
|
+
publishableKey: string;
|
|
15
|
+
statusUrl?: string;
|
|
16
|
+
reconciliationUrl?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface FormConfiguration {
|
|
19
|
+
charity: {
|
|
20
|
+
name: string;
|
|
21
|
+
logoUrl: string | null;
|
|
22
|
+
primaryColor: string;
|
|
23
|
+
};
|
|
24
|
+
copy: {
|
|
25
|
+
title: string;
|
|
26
|
+
description: string | null;
|
|
27
|
+
impactMessage: string | null;
|
|
28
|
+
submitLabel: string;
|
|
29
|
+
};
|
|
30
|
+
currency: 'cad';
|
|
31
|
+
suggestedAmountsCents: number[];
|
|
32
|
+
minimumAmountCents: number;
|
|
33
|
+
allowCustomAmount: boolean;
|
|
34
|
+
allowCostCoverage: boolean;
|
|
35
|
+
defaultCoverCosts: boolean;
|
|
36
|
+
}
|
|
37
|
+
export declare function parseFormConfiguration(value: unknown): FormConfiguration;
|
|
38
|
+
export declare function resolveAccentColors(primaryColor: string, accentColor?: string, accentTextColor?: string): {
|
|
39
|
+
accentColor: string;
|
|
40
|
+
accentTextColor: string;
|
|
41
|
+
};
|
|
42
|
+
export declare function buildDonationUrl(apiUrl: string, charitySlug: string, formSlug: string): string;
|
|
43
|
+
export declare function buildFormConfigurationUrl(apiUrl: string, charitySlug: string, formSlug: string): string;
|
|
44
|
+
export declare function getFormConfiguration(apiUrl: string, charitySlug: string, formSlug: string, signal?: AbortSignal, fetcher?: typeof fetch): Promise<FormConfiguration>;
|
|
45
|
+
export declare function getReconciliationUrl(response: DonationStartResponse, apiUrl: string): string;
|
|
46
|
+
export declare function createDonationRequest(amountCents: number, firstName: string, lastName: string, email: string, coverCosts: boolean): DonationRequest;
|
|
47
|
+
export declare function mapDonationStatus(status: string | null | undefined): DonationStatus;
|
|
48
|
+
export declare function postJson<T>(url: string, body: unknown, headers?: Record<string, string>, fetcher?: typeof fetch): Promise<T>;
|
|
49
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GACtB,YAAY,GAAG,uBAAuB,GAAG,WAAW,GAAG,QAAQ,CAAC;AAEpE,MAAM,WAAW,eAAe;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE;QACH,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,UAAU,EAAE,IAAI,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,qBAAqB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,iBAAiB;IAC9B,OAAO,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,YAAY,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,IAAI,EAAE;QACF,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,WAAW,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,QAAQ,EAAE,KAAK,CAAC;IAChB,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,iBAAiB,EAAE,OAAO,CAAC;CAC9B;AAUD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,iBAAiB,CA6CxE;AAED,wBAAgB,mBAAmB,CAC/B,YAAY,EAAE,MAAM,EACpB,WAAW,CAAC,EAAE,MAAM,EACpB,eAAe,CAAC,EAAE,MAAM,GACzB;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,CAoClD;AAED,wBAAgB,gBAAgB,CAC5B,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACjB,MAAM,CAIR;AAED,wBAAgB,yBAAyB,CACrC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACjB,MAAM,CAIR;AAED,wBAAsB,oBAAoB,CACtC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,WAAW,EACpB,OAAO,GAAE,OAAO,KAAa,GAC9B,OAAO,CAAC,iBAAiB,CAAC,CAqB5B;AAED,wBAAgB,oBAAoB,CAChC,QAAQ,EAAE,qBAAqB,EAC/B,MAAM,EAAE,MAAM,GACf,MAAM,CAeR;AAED,wBAAgB,qBAAqB,CACjC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,OAAO,GACpB,eAAe,CAiBjB;AAED,wBAAgB,iBAAiB,CAC7B,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAClC,cAAc,CAqBhB;AAaD,wBAAsB,QAAQ,CAAC,CAAC,EAC5B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,OAAO,EACb,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,EACpC,OAAO,GAAE,OAAO,KAAa,GAC9B,OAAO,CAAC,CAAC,CAAC,CAsBZ"}
|
package/dist/helpers.js
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
function isRecord(value) {
|
|
2
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
3
|
+
}
|
|
4
|
+
function isNullableString(value) {
|
|
5
|
+
return typeof value === 'string' || value === null;
|
|
6
|
+
}
|
|
7
|
+
export function parseFormConfiguration(value) {
|
|
8
|
+
if (!isRecord(value) || !isRecord(value.charity) || !isRecord(value.copy)) {
|
|
9
|
+
throw new Error('GivingLite returned an invalid form configuration.');
|
|
10
|
+
}
|
|
11
|
+
const { charity, copy } = value;
|
|
12
|
+
const amounts = value.suggestedAmountsCents;
|
|
13
|
+
const minimumAmount = value.minimumAmountCents;
|
|
14
|
+
const allowCustomAmount = value.allowCustomAmount;
|
|
15
|
+
const allowCostCoverage = value.allowCostCoverage;
|
|
16
|
+
const valid = typeof charity.name === 'string' &&
|
|
17
|
+
charity.name.trim() !== '' &&
|
|
18
|
+
isNullableString(charity.logoUrl) &&
|
|
19
|
+
typeof charity.primaryColor === 'string' &&
|
|
20
|
+
/^#[0-9a-f]{6}$/i.test(charity.primaryColor) &&
|
|
21
|
+
typeof copy.title === 'string' &&
|
|
22
|
+
copy.title.trim() !== '' &&
|
|
23
|
+
isNullableString(copy.description) &&
|
|
24
|
+
isNullableString(copy.impactMessage) &&
|
|
25
|
+
typeof copy.submitLabel === 'string' &&
|
|
26
|
+
copy.submitLabel.trim() !== '' &&
|
|
27
|
+
value.currency === 'cad' &&
|
|
28
|
+
Array.isArray(amounts) &&
|
|
29
|
+
Number.isSafeInteger(minimumAmount) &&
|
|
30
|
+
minimumAmount > 0 &&
|
|
31
|
+
minimumAmount <= 1000000 &&
|
|
32
|
+
typeof allowCustomAmount === 'boolean' &&
|
|
33
|
+
(amounts.length > 0 || allowCustomAmount === true) &&
|
|
34
|
+
amounts.every((amount) => Number.isSafeInteger(amount) &&
|
|
35
|
+
amount >= minimumAmount &&
|
|
36
|
+
amount <= 1000000) &&
|
|
37
|
+
new Set(amounts).size === amounts.length &&
|
|
38
|
+
typeof allowCostCoverage === 'boolean' &&
|
|
39
|
+
typeof value.defaultCoverCosts === 'boolean' &&
|
|
40
|
+
(allowCostCoverage === true || value.defaultCoverCosts === false);
|
|
41
|
+
if (!valid) {
|
|
42
|
+
throw new Error('GivingLite returned an invalid form configuration.');
|
|
43
|
+
}
|
|
44
|
+
return value;
|
|
45
|
+
}
|
|
46
|
+
export function resolveAccentColors(primaryColor, accentColor, accentTextColor) {
|
|
47
|
+
const safeColor = /^#[0-9a-f]{6}$/i;
|
|
48
|
+
const resolvedAccent = safeColor.test(accentColor ?? '')
|
|
49
|
+
? accentColor
|
|
50
|
+
: safeColor.test(primaryColor)
|
|
51
|
+
? primaryColor
|
|
52
|
+
: '#155e75';
|
|
53
|
+
if (safeColor.test(accentTextColor ?? '')) {
|
|
54
|
+
return {
|
|
55
|
+
accentColor: resolvedAccent,
|
|
56
|
+
accentTextColor: accentTextColor,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
const channels = [1, 3, 5].map((offset) => Number.parseInt(resolvedAccent.slice(offset, offset + 2), 16));
|
|
60
|
+
const luminance = channels
|
|
61
|
+
.map((channel) => {
|
|
62
|
+
const value = channel / 255;
|
|
63
|
+
return value <= 0.04045
|
|
64
|
+
? value / 12.92
|
|
65
|
+
: ((value + 0.055) / 1.055) ** 2.4;
|
|
66
|
+
})
|
|
67
|
+
.reduce((total, channel, index) => total + channel * [0.2126, 0.7152, 0.0722][index], 0);
|
|
68
|
+
return {
|
|
69
|
+
accentColor: resolvedAccent,
|
|
70
|
+
accentTextColor: luminance <= 0.179 ? '#ffffff' : '#0f172a',
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
export function buildDonationUrl(apiUrl, charitySlug, formSlug) {
|
|
74
|
+
const base = apiUrl.replace(/\/+$/, '');
|
|
75
|
+
return `${base}/api/v1/charities/${encodeURIComponent(charitySlug)}/forms/${encodeURIComponent(formSlug)}/donations`;
|
|
76
|
+
}
|
|
77
|
+
export function buildFormConfigurationUrl(apiUrl, charitySlug, formSlug) {
|
|
78
|
+
const base = apiUrl.replace(/\/+$/, '');
|
|
79
|
+
return `${base}/api/v1/charities/${encodeURIComponent(charitySlug)}/forms/${encodeURIComponent(formSlug)}/configuration`;
|
|
80
|
+
}
|
|
81
|
+
export async function getFormConfiguration(apiUrl, charitySlug, formSlug, signal, fetcher = fetch) {
|
|
82
|
+
const response = await fetcher(buildFormConfigurationUrl(apiUrl, charitySlug, formSlug), {
|
|
83
|
+
method: 'GET',
|
|
84
|
+
headers: { Accept: 'application/json' },
|
|
85
|
+
signal,
|
|
86
|
+
});
|
|
87
|
+
const result = await readJson(response, 'form configuration');
|
|
88
|
+
if (!response.ok) {
|
|
89
|
+
const message = isRecord(result) && typeof result.message === 'string'
|
|
90
|
+
? result.message
|
|
91
|
+
: `GivingLite request failed (${response.status}).`;
|
|
92
|
+
throw new Error(message);
|
|
93
|
+
}
|
|
94
|
+
return parseFormConfiguration(result);
|
|
95
|
+
}
|
|
96
|
+
export function getReconciliationUrl(response, apiUrl) {
|
|
97
|
+
const candidate = response.statusUrl ?? response.reconciliationUrl;
|
|
98
|
+
if (!candidate) {
|
|
99
|
+
throw new Error('GivingLite did not return a reconciliation URL.');
|
|
100
|
+
}
|
|
101
|
+
const url = new URL(candidate, `${apiUrl.replace(/\/+$/, '')}/`);
|
|
102
|
+
const apiOrigin = new URL(apiUrl).origin;
|
|
103
|
+
if (url.origin !== apiOrigin) {
|
|
104
|
+
throw new Error('GivingLite returned an untrusted reconciliation URL.');
|
|
105
|
+
}
|
|
106
|
+
return url.toString();
|
|
107
|
+
}
|
|
108
|
+
export function createDonationRequest(amountCents, firstName, lastName, email, coverCosts) {
|
|
109
|
+
if (!Number.isSafeInteger(amountCents) || amountCents <= 0) {
|
|
110
|
+
throw new Error('Donation amount must be a positive integer number of cents.');
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
amount: amountCents,
|
|
114
|
+
donor: {
|
|
115
|
+
firstName: firstName.trim(),
|
|
116
|
+
lastName: lastName.trim(),
|
|
117
|
+
email: email.trim(),
|
|
118
|
+
},
|
|
119
|
+
campaignId: null,
|
|
120
|
+
coverCosts,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
export function mapDonationStatus(status) {
|
|
124
|
+
switch (status) {
|
|
125
|
+
case 'succeeded':
|
|
126
|
+
case 'paid':
|
|
127
|
+
case 'completed':
|
|
128
|
+
return 'succeeded';
|
|
129
|
+
case 'processing':
|
|
130
|
+
case 'pending':
|
|
131
|
+
return 'processing';
|
|
132
|
+
case 'requires_action':
|
|
133
|
+
case 'requires_confirmation':
|
|
134
|
+
case 'verification_required':
|
|
135
|
+
case 'verification-required':
|
|
136
|
+
return 'verification-required';
|
|
137
|
+
case 'canceled':
|
|
138
|
+
case 'failed':
|
|
139
|
+
case 'requires_payment_method':
|
|
140
|
+
return 'failed';
|
|
141
|
+
default:
|
|
142
|
+
return 'processing';
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
async function readJson(response, resource) {
|
|
146
|
+
try {
|
|
147
|
+
return await response.json();
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
throw new Error(`GivingLite returned an invalid ${resource} response.`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
export async function postJson(url, body, headers = {}, fetcher = fetch) {
|
|
154
|
+
const hasBody = body !== undefined;
|
|
155
|
+
const response = await fetcher(url, {
|
|
156
|
+
method: 'POST',
|
|
157
|
+
headers: {
|
|
158
|
+
Accept: 'application/json',
|
|
159
|
+
...(hasBody ? { 'Content-Type': 'application/json' } : {}),
|
|
160
|
+
...headers,
|
|
161
|
+
},
|
|
162
|
+
...(hasBody ? { body: JSON.stringify(body) } : {}),
|
|
163
|
+
});
|
|
164
|
+
const result = (await readJson(response, 'JSON'));
|
|
165
|
+
if (!response.ok) {
|
|
166
|
+
throw new Error(result.message ?? `GivingLite request failed (${response.status}).`);
|
|
167
|
+
}
|
|
168
|
+
return result;
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { buildDonationUrl, buildFormConfigurationUrl, createDonationRequest, getFormConfiguration, getReconciliationUrl, mapDonationStatus, parseFormConfiguration, postJson, resolveAccentColors } from './helpers.js';
|
|
2
|
+
import type { DonationStatus } from './helpers.js';
|
|
3
|
+
import { loadStripeJs } from './stripe.js';
|
|
4
|
+
import type { StripeLoader } from './stripe.js';
|
|
5
|
+
export { buildDonationUrl, buildFormConfigurationUrl, createDonationRequest, getFormConfiguration, getReconciliationUrl, loadStripeJs, mapDonationStatus, parseFormConfiguration, postJson, resolveAccentColors, };
|
|
6
|
+
export type { DonationRequest, DonationStartResponse, DonationStatus, FormConfiguration, } from './helpers.js';
|
|
7
|
+
export type { GivingLiteStripe, StripeLoader, StripePaymentIntent, } from './stripe.js';
|
|
8
|
+
export interface DonationResult {
|
|
9
|
+
idempotencyKey: string;
|
|
10
|
+
paymentIntentId: string;
|
|
11
|
+
status: DonationStatus;
|
|
12
|
+
}
|
|
13
|
+
export interface GivingLiteDonationFormProps {
|
|
14
|
+
apiUrl: string;
|
|
15
|
+
charitySlug: string;
|
|
16
|
+
formSlug: string;
|
|
17
|
+
branding?: {
|
|
18
|
+
accentColor?: string;
|
|
19
|
+
accentTextColor?: string;
|
|
20
|
+
};
|
|
21
|
+
copy?: {
|
|
22
|
+
title?: string;
|
|
23
|
+
description?: string;
|
|
24
|
+
amountLabel?: string;
|
|
25
|
+
coverCostsLabel?: string;
|
|
26
|
+
submitLabel?: string;
|
|
27
|
+
secureMessage?: string;
|
|
28
|
+
};
|
|
29
|
+
stripeLoader?: StripeLoader;
|
|
30
|
+
fetcher?: typeof fetch;
|
|
31
|
+
onStarted?: (details: {
|
|
32
|
+
amountCents: number;
|
|
33
|
+
idempotencyKey: string;
|
|
34
|
+
}) => void;
|
|
35
|
+
onComplete?: (result: DonationResult) => void;
|
|
36
|
+
onError?: (error: Error) => void;
|
|
37
|
+
}
|
|
38
|
+
export declare function GivingLiteDonationForm({ apiUrl, charitySlug, formSlug, branding, copy, stripeLoader, fetcher, onStarted, onComplete, onError, }: GivingLiteDonationFormProps): import("react").JSX.Element;
|
|
39
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAKA,OAAO,EACH,gBAAgB,EAChB,yBAAyB,EACzB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,QAAQ,EACR,mBAAmB,EACtB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAER,cAAc,EAEjB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,OAAO,EACH,gBAAgB,EAChB,yBAAyB,EACzB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,YAAY,EACZ,iBAAiB,EACjB,sBAAsB,EACtB,QAAQ,EACR,mBAAmB,GACtB,CAAC;AACF,YAAY,EACR,eAAe,EACf,qBAAqB,EACrB,cAAc,EACd,iBAAiB,GACpB,MAAM,cAAc,CAAC;AACtB,YAAY,EACR,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,GACtB,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,cAAc;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,cAAc,CAAC;CAC1B;AAED,MAAM,WAAW,2BAA2B;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE;QACP,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC5B,CAAC;IACF,IAAI,CAAC,EAAE;QACH,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,aAAa,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IACvB,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,EAAE,MAAM,CAAC;KAC1B,KAAK,IAAI,CAAC;IACX,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;IAC9C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACpC;AAmDD,wBAAgB,sBAAsB,CAAC,EACnC,MAAM,EACN,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,IAAI,EACJ,YAA2B,EAC3B,OAAe,EACf,SAAS,EACT,UAAU,EACV,OAAO,GACV,EAAE,2BAA2B,+BAqd7B"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useId, useRef, useState } from 'react';
|
|
4
|
+
import { buildDonationUrl, buildFormConfigurationUrl, createDonationRequest, getFormConfiguration, getReconciliationUrl, mapDonationStatus, parseFormConfiguration, postJson, resolveAccentColors, } from './helpers.js';
|
|
5
|
+
import { loadStripeJs } from './stripe.js';
|
|
6
|
+
import { styles } from './styles.js';
|
|
7
|
+
export { buildDonationUrl, buildFormConfigurationUrl, createDonationRequest, getFormConfiguration, getReconciliationUrl, loadStripeJs, mapDonationStatus, parseFormConfiguration, postJson, resolveAccentColors, };
|
|
8
|
+
const statusCopy = {
|
|
9
|
+
processing: 'Your donation is processing. Canadian bank debits can take several business days to settle.',
|
|
10
|
+
'verification-required': 'Your bank needs additional verification. Follow the instructions from Stripe to continue.',
|
|
11
|
+
succeeded: 'Your donation was successfully submitted. Thank you.',
|
|
12
|
+
failed: 'Your donation could not be completed. Please try again.',
|
|
13
|
+
};
|
|
14
|
+
function dollarsToCents(value) {
|
|
15
|
+
if (!/^\d+(?:\.\d{1,2})?$/.test(value.trim())) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
const cents = Math.round(Number(value) * 100);
|
|
19
|
+
return Number.isSafeInteger(cents) ? cents : null;
|
|
20
|
+
}
|
|
21
|
+
function formatCad(cents) {
|
|
22
|
+
return new Intl.NumberFormat('en-CA', {
|
|
23
|
+
style: 'currency',
|
|
24
|
+
currency: 'CAD',
|
|
25
|
+
maximumFractionDigits: 2,
|
|
26
|
+
}).format(cents / 100);
|
|
27
|
+
}
|
|
28
|
+
export function GivingLiteDonationForm({ apiUrl, charitySlug, formSlug, branding, copy, stripeLoader = loadStripeJs, fetcher = fetch, onStarted, onComplete, onError, }) {
|
|
29
|
+
const id = useId();
|
|
30
|
+
const submitting = useRef(false);
|
|
31
|
+
const errorCallback = useRef(onError);
|
|
32
|
+
const [configurationResult, setConfigurationResult] = useState(null);
|
|
33
|
+
const [configurationFailure, setConfigurationFailure] = useState(null);
|
|
34
|
+
const [amount, setAmount] = useState('');
|
|
35
|
+
const [firstName, setFirstName] = useState('');
|
|
36
|
+
const [lastName, setLastName] = useState('');
|
|
37
|
+
const [email, setEmail] = useState('');
|
|
38
|
+
const [coverCosts, setCoverCosts] = useState(false);
|
|
39
|
+
const [busy, setBusy] = useState(false);
|
|
40
|
+
const [status, setStatus] = useState(null);
|
|
41
|
+
const [message, setMessage] = useState('');
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
errorCallback.current = onError;
|
|
44
|
+
}, [onError]);
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
const controller = new AbortController();
|
|
47
|
+
let current = true;
|
|
48
|
+
void getFormConfiguration(apiUrl, charitySlug, formSlug, controller.signal, fetcher)
|
|
49
|
+
.then((loaded) => {
|
|
50
|
+
if (!current) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
setConfigurationResult({
|
|
54
|
+
apiUrl,
|
|
55
|
+
charitySlug,
|
|
56
|
+
formSlug,
|
|
57
|
+
fetcher,
|
|
58
|
+
value: loaded,
|
|
59
|
+
});
|
|
60
|
+
setConfigurationFailure(null);
|
|
61
|
+
setAmount(((loaded.suggestedAmountsCents[0] ??
|
|
62
|
+
loaded.minimumAmountCents) / 100).toFixed(2));
|
|
63
|
+
setCoverCosts(loaded.allowCostCoverage && loaded.defaultCoverCosts);
|
|
64
|
+
setStatus(null);
|
|
65
|
+
setMessage('');
|
|
66
|
+
})
|
|
67
|
+
.catch((caught) => {
|
|
68
|
+
if (!current || controller.signal.aborted) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const error = caught instanceof Error
|
|
72
|
+
? caught
|
|
73
|
+
: new Error('The donation form configuration could not be loaded.');
|
|
74
|
+
setConfigurationFailure({
|
|
75
|
+
apiUrl,
|
|
76
|
+
charitySlug,
|
|
77
|
+
formSlug,
|
|
78
|
+
fetcher,
|
|
79
|
+
message: error.message,
|
|
80
|
+
});
|
|
81
|
+
errorCallback.current?.(error);
|
|
82
|
+
});
|
|
83
|
+
return () => {
|
|
84
|
+
current = false;
|
|
85
|
+
controller.abort();
|
|
86
|
+
};
|
|
87
|
+
}, [apiUrl, charitySlug, fetcher, formSlug]);
|
|
88
|
+
const isCurrentRequest = (result) => result.apiUrl === apiUrl &&
|
|
89
|
+
result.charitySlug === charitySlug &&
|
|
90
|
+
result.formSlug === formSlug &&
|
|
91
|
+
result.fetcher === fetcher;
|
|
92
|
+
const configuration = configurationResult && isCurrentRequest(configurationResult)
|
|
93
|
+
? configurationResult.value
|
|
94
|
+
: null;
|
|
95
|
+
const configurationError = configurationFailure && isCurrentRequest(configurationFailure)
|
|
96
|
+
? configurationFailure.message
|
|
97
|
+
: '';
|
|
98
|
+
if (!configuration) {
|
|
99
|
+
return (_jsxs(_Fragment, { children: [_jsx("style", { children: styles }), _jsx("section", { className: "glr-pad", "aria-busy": !configurationError, children: configurationError ? (_jsx("p", { className: "glr-pad__status glr-pad__status--failed", role: "alert", children: configurationError })) : (_jsx("p", { className: "glr-pad__status", role: "status", children: "Loading donation form..." })) })] }));
|
|
100
|
+
}
|
|
101
|
+
const { suggestedAmountsCents, minimumAmountCents, allowCustomAmount, allowCostCoverage, } = configuration;
|
|
102
|
+
const amountCents = dollarsToCents(amount);
|
|
103
|
+
const selectedSuggestion = suggestedAmountsCents.find((suggestion) => suggestion === amountCents);
|
|
104
|
+
const colors = resolveAccentColors(configuration.charity.primaryColor, branding?.accentColor, branding?.accentTextColor);
|
|
105
|
+
const style = {
|
|
106
|
+
'--glr-accent': colors.accentColor,
|
|
107
|
+
'--glr-accent-text': colors.accentTextColor,
|
|
108
|
+
};
|
|
109
|
+
const submit = async (event) => {
|
|
110
|
+
event.preventDefault();
|
|
111
|
+
if (submitting.current) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (amountCents === null || amountCents < minimumAmountCents) {
|
|
115
|
+
setStatus('failed');
|
|
116
|
+
setMessage(`The minimum donation is ${formatCad(minimumAmountCents)}.`);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (!allowCustomAmount && selectedSuggestion === undefined) {
|
|
120
|
+
setStatus('failed');
|
|
121
|
+
setMessage('Select one of the available donation amounts.');
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
submitting.current = true;
|
|
125
|
+
setBusy(true);
|
|
126
|
+
setStatus(null);
|
|
127
|
+
setMessage('Starting your secure bank payment...');
|
|
128
|
+
const idempotencyKey = crypto.randomUUID();
|
|
129
|
+
try {
|
|
130
|
+
const request = createDonationRequest(amountCents, firstName, lastName, email, allowCostCoverage && coverCosts);
|
|
131
|
+
onStarted?.({ amountCents, idempotencyKey });
|
|
132
|
+
const started = await postJson(buildDonationUrl(apiUrl, charitySlug, formSlug), request, { 'Idempotency-Key': idempotencyKey }, fetcher);
|
|
133
|
+
if (!started.clientSecret || !started.publishableKey) {
|
|
134
|
+
throw new Error('GivingLite returned an invalid payment response.');
|
|
135
|
+
}
|
|
136
|
+
setMessage('Complete the secure bank authorization with Stripe.');
|
|
137
|
+
const stripe = await stripeLoader(started.publishableKey);
|
|
138
|
+
const confirmation = await stripe.confirmAcssDebitPayment(started.clientSecret, {
|
|
139
|
+
payment_method: {
|
|
140
|
+
billing_details: {
|
|
141
|
+
name: `${request.donor.firstName} ${request.donor.lastName}`,
|
|
142
|
+
email: request.donor.email,
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
const paymentIntent = confirmation.paymentIntent ??
|
|
147
|
+
confirmation.error?.payment_intent;
|
|
148
|
+
if (!paymentIntent) {
|
|
149
|
+
throw new Error(confirmation.error?.message ??
|
|
150
|
+
'Stripe did not return a payment result.');
|
|
151
|
+
}
|
|
152
|
+
setMessage('Confirming your donation with GivingLite...');
|
|
153
|
+
const reconciled = await postJson(getReconciliationUrl(started, apiUrl), undefined, {}, fetcher);
|
|
154
|
+
const finalStatus = mapDonationStatus(reconciled.stripeStatus ??
|
|
155
|
+
reconciled.paymentStatus ??
|
|
156
|
+
reconciled.status ??
|
|
157
|
+
paymentIntent.status);
|
|
158
|
+
const result = {
|
|
159
|
+
idempotencyKey,
|
|
160
|
+
paymentIntentId: paymentIntent.id,
|
|
161
|
+
status: finalStatus,
|
|
162
|
+
};
|
|
163
|
+
setStatus(finalStatus);
|
|
164
|
+
setMessage(statusCopy[finalStatus]);
|
|
165
|
+
if (finalStatus === 'failed') {
|
|
166
|
+
const error = new Error(confirmation.error?.message ?? statusCopy.failed);
|
|
167
|
+
onError?.(error);
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
onComplete?.(result);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
catch (caught) {
|
|
174
|
+
const error = caught instanceof Error
|
|
175
|
+
? caught
|
|
176
|
+
: new Error('The donation could not be completed.');
|
|
177
|
+
setStatus('failed');
|
|
178
|
+
setMessage(error.message);
|
|
179
|
+
onError?.(error);
|
|
180
|
+
}
|
|
181
|
+
finally {
|
|
182
|
+
submitting.current = false;
|
|
183
|
+
setBusy(false);
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
return (_jsxs(_Fragment, { children: [_jsx("style", { children: styles }), _jsxs("form", { className: "glr-pad", style: style, onSubmit: (event) => void submit(event), "aria-busy": busy, children: [_jsxs("header", { className: "glr-pad__header", children: [(configuration.charity.logoUrl ||
|
|
187
|
+
configuration.charity.name) && (_jsxs("div", { className: "glr-pad__charity", children: [configuration.charity.logoUrl && (_jsx("img", { className: "glr-pad__logo", src: configuration.charity.logoUrl, alt: "" })), configuration.charity.name && (_jsx("span", { children: configuration.charity.name }))] })), _jsx("h2", { className: "glr-pad__title", children: copy?.title ?? configuration.copy.title }), (copy?.description ?? configuration.copy.description) && (_jsx("p", { className: "glr-pad__description", children: copy?.description ??
|
|
188
|
+
configuration.copy.description })), configuration.copy.impactMessage && (_jsx("p", { className: "glr-pad__impact", children: configuration.copy.impactMessage }))] }), _jsxs("fieldset", { className: "glr-pad__fieldset", disabled: busy, children: [_jsx("legend", { className: "glr-pad__legend", children: copy?.amountLabel ?? 'Donation amount (CAD)' }), _jsx("div", { className: "glr-pad__amounts", children: suggestedAmountsCents.map((suggestion) => (_jsx("button", { className: "glr-pad__amount-button", type: "button", "aria-pressed": selectedSuggestion === suggestion, onClick: () => setAmount((suggestion / 100).toFixed(2)), children: formatCad(suggestion) }, suggestion))) }), allowCustomAmount && (_jsxs(_Fragment, { children: [_jsx("label", { className: "glr-pad__label", htmlFor: `${id}-amount`, children: "Other amount" }), _jsxs("div", { className: "glr-pad__money", children: [_jsx("span", { className: "glr-pad__money-prefix", "aria-hidden": "true", children: "$" }), _jsx("input", { className: "glr-pad__input", id: `${id}-amount`, name: "amount", type: "text", inputMode: "decimal", autoComplete: "off", value: amount, onChange: (event) => setAmount(event.target.value), "aria-describedby": `${id}-amount-hint`, required: true })] })] })), _jsxs("p", { className: "glr-pad__hint", id: `${id}-amount-hint`, children: ["Minimum ", formatCad(minimumAmountCents), ". Amounts are in CAD."] })] }), _jsxs("div", { className: "glr-pad__grid", children: [_jsxs("div", { className: "glr-pad__field", children: [_jsx("label", { className: "glr-pad__label", htmlFor: `${id}-first`, children: "First name" }), _jsx("input", { className: "glr-pad__input", id: `${id}-first`, name: "firstName", autoComplete: "given-name", value: firstName, onChange: (event) => setFirstName(event.target.value), disabled: busy, required: true })] }), _jsxs("div", { className: "glr-pad__field", children: [_jsx("label", { className: "glr-pad__label", htmlFor: `${id}-last`, children: "Last name" }), _jsx("input", { className: "glr-pad__input", id: `${id}-last`, name: "lastName", autoComplete: "family-name", value: lastName, onChange: (event) => setLastName(event.target.value), disabled: busy, required: true })] })] }), _jsxs("div", { className: "glr-pad__field", children: [_jsx("label", { className: "glr-pad__label", htmlFor: `${id}-email`, children: "Email address" }), _jsx("input", { className: "glr-pad__input", id: `${id}-email`, name: "email", type: "email", autoComplete: "email", value: email, onChange: (event) => setEmail(event.target.value), disabled: busy, required: true })] }), allowCostCoverage && (_jsxs("label", { className: "glr-pad__check", children: [_jsx("input", { type: "checkbox", checked: coverCosts, onChange: (event) => setCoverCosts(event.target.checked), disabled: busy }), _jsx("span", { children: copy?.coverCostsLabel ??
|
|
189
|
+
'I would like to help cover processing costs.' })] })), _jsx("button", { className: "glr-pad__submit", type: "submit", disabled: busy, children: busy
|
|
190
|
+
? 'Please wait...'
|
|
191
|
+
: (copy?.submitLabel ?? configuration.copy.submitLabel) }), message && (_jsx("p", { className: `glr-pad__status${status === 'failed' ? 'glr-pad__status--failed' : ''}`, role: status === 'failed' ? 'alert' : 'status', "aria-live": "polite", children: message })), _jsx("p", { className: "glr-pad__secure", children: copy?.secureMessage ??
|
|
192
|
+
'Stripe securely collects your bank details. GivingLite and this page never receive them.' })] })] }));
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"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"}
|
package/dist/stripe.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface StripePaymentIntent {
|
|
2
|
+
id: string;
|
|
3
|
+
status: string;
|
|
4
|
+
}
|
|
5
|
+
export interface StripeError {
|
|
6
|
+
message?: string;
|
|
7
|
+
payment_intent?: StripePaymentIntent;
|
|
8
|
+
}
|
|
9
|
+
export interface GivingLiteStripe {
|
|
10
|
+
confirmAcssDebitPayment(clientSecret: string, data: {
|
|
11
|
+
payment_method: {
|
|
12
|
+
billing_details: {
|
|
13
|
+
name: string;
|
|
14
|
+
email: string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
}): Promise<{
|
|
18
|
+
error?: StripeError;
|
|
19
|
+
paymentIntent?: StripePaymentIntent;
|
|
20
|
+
}>;
|
|
21
|
+
}
|
|
22
|
+
export type StripeLoader = (publishableKey: string) => Promise<GivingLiteStripe>;
|
|
23
|
+
export declare const loadStripeJs: StripeLoader;
|
|
24
|
+
//# sourceMappingURL=stripe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stripe.d.ts","sourceRoot":"","sources":["../src/stripe.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,mBAAmB,CAAC;CACxC;AAED,MAAM,WAAW,gBAAgB;IAC7B,uBAAuB,CACnB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE;QACF,cAAc,EAAE;YACZ,eAAe,EAAE;gBACb,IAAI,EAAE,MAAM,CAAC;gBACb,KAAK,EAAE,MAAM,CAAC;aACjB,CAAC;SACL,CAAC;KACL,GACF,OAAO,CAAC;QACP,KAAK,CAAC,EAAE,WAAW,CAAC;QACpB,aAAa,CAAC,EAAE,mBAAmB,CAAC;KACvC,CAAC,CAAC;CACN;AAED,MAAM,MAAM,YAAY,GAAG,CACvB,cAAc,EAAE,MAAM,KACrB,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAM/B,eAAO,MAAM,YAAY,EAAE,YAgD1B,CAAC"}
|
package/dist/stripe.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
let stripeScriptPromise;
|
|
2
|
+
export const loadStripeJs = async (publishableKey) => {
|
|
3
|
+
if (typeof window === 'undefined' || typeof document === 'undefined') {
|
|
4
|
+
throw new Error('Stripe.js can only be loaded in a browser.');
|
|
5
|
+
}
|
|
6
|
+
const stripeWindow = window;
|
|
7
|
+
if (!stripeWindow.Stripe) {
|
|
8
|
+
stripeScriptPromise ?? (stripeScriptPromise = new Promise((resolve, reject) => {
|
|
9
|
+
const existing = document.querySelector('script[src="https://js.stripe.com/v3/"]');
|
|
10
|
+
const script = existing ?? document.createElement('script');
|
|
11
|
+
const loaded = () => {
|
|
12
|
+
if (stripeWindow.Stripe) {
|
|
13
|
+
resolve(stripeWindow.Stripe);
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
reject(new Error('Stripe.js loaded without initializing.'));
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
const failed = () => reject(new Error('Stripe.js could not be loaded.'));
|
|
20
|
+
script.addEventListener('load', loaded, { once: true });
|
|
21
|
+
script.addEventListener('error', failed, { once: true });
|
|
22
|
+
if (!existing) {
|
|
23
|
+
script.src = 'https://js.stripe.com/v3/';
|
|
24
|
+
script.async = true;
|
|
25
|
+
document.head.appendChild(script);
|
|
26
|
+
}
|
|
27
|
+
}));
|
|
28
|
+
await stripeScriptPromise;
|
|
29
|
+
}
|
|
30
|
+
const stripe = stripeWindow.Stripe?.(publishableKey);
|
|
31
|
+
if (!stripe) {
|
|
32
|
+
throw new Error('Stripe.js could not be initialized.');
|
|
33
|
+
}
|
|
34
|
+
return stripe;
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=stripe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stripe.js","sourceRoot":"","sources":["../src/stripe.ts"],"names":[],"mappings":"AAiCA,IAAI,mBAAuD,CAAC;AAE5D,MAAM,CAAC,MAAM,YAAY,GAAiB,KAAK,EAAE,cAAc,EAAE,EAAE;IAC/D,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;QACnE,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,YAAY,GAAG,MAAoD,CAAC;IAE1E,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;QACvB,mBAAmB,KAAnB,mBAAmB,GAAK,IAAI,OAAO,CAC/B,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAChB,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CACnC,yCAAyC,CAC5C,CAAC;YACF,MAAM,MAAM,GAAG,QAAQ,IAAI,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YAE5D,MAAM,MAAM,GAAG,GAAG,EAAE;gBAChB,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;oBACtB,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;gBACjC,CAAC;qBAAM,CAAC;oBACJ,MAAM,CACF,IAAI,KAAK,CAAC,wCAAwC,CAAC,CACtD,CAAC;gBACN,CAAC;YACL,CAAC,CAAC;YACF,MAAM,MAAM,GAAG,GAAG,EAAE,CAChB,MAAM,CAAC,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC,CAAC;YAExD,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACxD,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAEzD,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACZ,MAAM,CAAC,GAAG,GAAG,2BAA2B,CAAC;gBACzC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC;gBACpB,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YACtC,CAAC;QACL,CAAC,CACJ,EAAC;QAEF,MAAM,mBAAmB,CAAC;IAC9B,CAAC;IAED,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,cAAc,CAAC,CAAC;IAErD,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAC3D,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC,CAAC"}
|
package/dist/styles.d.ts
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const styles = "\n.glr-pad{--glr-accent:#155e75;--glr-accent-text:#fff;--glr-border:#cbd5e1;--glr-muted:#475569;--glr-error:#b91c1c;box-sizing:border-box;width:100%;max-width:36rem;padding:1.5rem;border:1px solid var(--glr-border);border-radius:1rem;background:#fff;color:#0f172a;font:400 16px/1.5 ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans-serif;box-shadow:0 16px 45px rgba(15,23,42,.08)}\n.glr-pad *{box-sizing:border-box}.glr-pad__header{margin-bottom:1.25rem}.glr-pad__charity{display:flex;align-items:center;gap:.6rem;margin-bottom:.85rem;font-weight:700}.glr-pad__logo{display:block;width:2.5rem;height:2.5rem;object-fit:contain}.glr-pad__title{margin:0;font-size:1.5rem;line-height:1.2}.glr-pad__description{margin:.4rem 0 0;color:var(--glr-muted)}.glr-pad__impact{margin:.8rem 0 0;padding:.7rem .8rem;border-left:3px solid var(--glr-accent);background:#f8fafc}\n.glr-pad__fieldset{padding:0;margin:0 0 1.25rem;border:0}.glr-pad__legend,.glr-pad__label{display:block;margin:0 0 .4rem;font-weight:650}.glr-pad__amounts{display:flex;flex-wrap:wrap;gap:.5rem;margin-bottom:.75rem}\n.glr-pad__amount-button{min-height:2.75rem;padding:.55rem .9rem;border:1px solid var(--glr-border);border-radius:.6rem;background:#fff;color:inherit;font:inherit;font-weight:650;cursor:pointer}.glr-pad__amount-button[aria-pressed=\"true\"]{border-color:var(--glr-accent);background:var(--glr-accent);color:var(--glr-accent-text)}\n.glr-pad__grid{display:grid;grid-template-columns:1fr 1fr;gap:1rem}.glr-pad__field{margin-bottom:1rem}.glr-pad__input{width:100%;min-height:2.75rem;padding:.6rem .7rem;border:1px solid var(--glr-border);border-radius:.6rem;background:#fff;color:#0f172a;font:inherit}.glr-pad__input:focus,.glr-pad__amount-button:focus,.glr-pad__submit:focus{outline:3px solid color-mix(in srgb,var(--glr-accent) 28%,transparent);outline-offset:2px}\n.glr-pad__money{display:flex;align-items:center}.glr-pad__money-prefix{align-self:stretch;display:grid;place-items:center;padding:0 .65rem;border:1px solid var(--glr-border);border-right:0;border-radius:.6rem 0 0 .6rem;background:#f8fafc}.glr-pad__money .glr-pad__input{border-radius:0 .6rem .6rem 0}.glr-pad__hint{margin:.35rem 0 0;color:var(--glr-muted);font-size:.875rem}.glr-pad__check{display:flex;align-items:flex-start;gap:.55rem;margin:0 0 1.25rem}.glr-pad__check input{margin-top:.3rem;accent-color:var(--glr-accent)}\n.glr-pad__submit{width:100%;min-height:3rem;padding:.7rem 1rem;border:0;border-radius:.65rem;background:var(--glr-accent);color:var(--glr-accent-text);font:inherit;font-weight:750;cursor:pointer}.glr-pad__submit:disabled{cursor:not-allowed;opacity:.62}.glr-pad__status{margin:1rem 0 0;padding:.75rem;border-radius:.5rem;background:#f1f5f9}.glr-pad__status--failed{background:#fef2f2;color:var(--glr-error)}.glr-pad__secure{margin:1rem 0 0;text-align:center;color:var(--glr-muted);font-size:.8rem}\n@media(max-width:32rem){.glr-pad{padding:1.1rem}.glr-pad__grid{grid-template-columns:1fr;gap:0}}\n";
|
|
2
|
+
//# sourceMappingURL=styles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,MAAM,m7FASlB,CAAC"}
|
package/dist/styles.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export const styles = `
|
|
2
|
+
.glr-pad{--glr-accent:#155e75;--glr-accent-text:#fff;--glr-border:#cbd5e1;--glr-muted:#475569;--glr-error:#b91c1c;box-sizing:border-box;width:100%;max-width:36rem;padding:1.5rem;border:1px solid var(--glr-border);border-radius:1rem;background:#fff;color:#0f172a;font:400 16px/1.5 ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;box-shadow:0 16px 45px rgba(15,23,42,.08)}
|
|
3
|
+
.glr-pad *{box-sizing:border-box}.glr-pad__header{margin-bottom:1.25rem}.glr-pad__charity{display:flex;align-items:center;gap:.6rem;margin-bottom:.85rem;font-weight:700}.glr-pad__logo{display:block;width:2.5rem;height:2.5rem;object-fit:contain}.glr-pad__title{margin:0;font-size:1.5rem;line-height:1.2}.glr-pad__description{margin:.4rem 0 0;color:var(--glr-muted)}.glr-pad__impact{margin:.8rem 0 0;padding:.7rem .8rem;border-left:3px solid var(--glr-accent);background:#f8fafc}
|
|
4
|
+
.glr-pad__fieldset{padding:0;margin:0 0 1.25rem;border:0}.glr-pad__legend,.glr-pad__label{display:block;margin:0 0 .4rem;font-weight:650}.glr-pad__amounts{display:flex;flex-wrap:wrap;gap:.5rem;margin-bottom:.75rem}
|
|
5
|
+
.glr-pad__amount-button{min-height:2.75rem;padding:.55rem .9rem;border:1px solid var(--glr-border);border-radius:.6rem;background:#fff;color:inherit;font:inherit;font-weight:650;cursor:pointer}.glr-pad__amount-button[aria-pressed="true"]{border-color:var(--glr-accent);background:var(--glr-accent);color:var(--glr-accent-text)}
|
|
6
|
+
.glr-pad__grid{display:grid;grid-template-columns:1fr 1fr;gap:1rem}.glr-pad__field{margin-bottom:1rem}.glr-pad__input{width:100%;min-height:2.75rem;padding:.6rem .7rem;border:1px solid var(--glr-border);border-radius:.6rem;background:#fff;color:#0f172a;font:inherit}.glr-pad__input:focus,.glr-pad__amount-button:focus,.glr-pad__submit:focus{outline:3px solid color-mix(in srgb,var(--glr-accent) 28%,transparent);outline-offset:2px}
|
|
7
|
+
.glr-pad__money{display:flex;align-items:center}.glr-pad__money-prefix{align-self:stretch;display:grid;place-items:center;padding:0 .65rem;border:1px solid var(--glr-border);border-right:0;border-radius:.6rem 0 0 .6rem;background:#f8fafc}.glr-pad__money .glr-pad__input{border-radius:0 .6rem .6rem 0}.glr-pad__hint{margin:.35rem 0 0;color:var(--glr-muted);font-size:.875rem}.glr-pad__check{display:flex;align-items:flex-start;gap:.55rem;margin:0 0 1.25rem}.glr-pad__check input{margin-top:.3rem;accent-color:var(--glr-accent)}
|
|
8
|
+
.glr-pad__submit{width:100%;min-height:3rem;padding:.7rem 1rem;border:0;border-radius:.65rem;background:var(--glr-accent);color:var(--glr-accent-text);font:inherit;font-weight:750;cursor:pointer}.glr-pad__submit:disabled{cursor:not-allowed;opacity:.62}.glr-pad__status{margin:1rem 0 0;padding:.75rem;border-radius:.5rem;background:#f1f5f9}.glr-pad__status--failed{background:#fef2f2;color:var(--glr-error)}.glr-pad__secure{margin:1rem 0 0;text-align:center;color:var(--glr-muted);font-size:.8rem}
|
|
9
|
+
@media(max-width:32rem){.glr-pad{padding:1.1rem}.glr-pad__grid{grid-template-columns:1fr;gap:0}}
|
|
10
|
+
`;
|
|
11
|
+
//# sourceMappingURL=styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,MAAM,GAAG;;;;;;;;;CASrB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@givinglite/react",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Native React donation form for GivingLite Canadian PAD donations",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"README.md",
|
|
10
|
+
"LICENSE"
|
|
11
|
+
],
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"main": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsc -p tsconfig.build.json",
|
|
22
|
+
"test": "npm run build && node --test test/*.test.js",
|
|
23
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"react": ">=18 <20"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@types/react": "^19.2.0",
|
|
30
|
+
"react": "^19.2.0",
|
|
31
|
+
"typescript": "^5.7.2"
|
|
32
|
+
},
|
|
33
|
+
"engines": {
|
|
34
|
+
"node": ">=18"
|
|
35
|
+
},
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public"
|
|
39
|
+
}
|
|
40
|
+
}
|