@paykit-sdk/chapa 1.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.
- package/README.md +157 -0
- package/dist/chapa-provider.d.mts +58 -0
- package/dist/chapa-provider.d.ts +58 -0
- package/dist/chapa-provider.js +4607 -0
- package/dist/chapa-provider.mjs +4605 -0
- package/dist/index.d.mts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +4625 -0
- package/dist/index.mjs +4621 -0
- package/dist/schema.d.mts +194 -0
- package/dist/schema.d.ts +194 -0
- package/dist/schema.js +6 -0
- package/dist/schema.mjs +4 -0
- package/dist/utils/mapper.d.mts +41 -0
- package/dist/utils/mapper.d.ts +41 -0
- package/dist/utils/mapper.js +105 -0
- package/dist/utils/mapper.mjs +99 -0
- package/package.json +46 -0
package/README.md
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# @paykit-sdk/chapa
|
|
2
|
+
|
|
3
|
+
Chapa provider for PayKit.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @paykit-sdk/chapa
|
|
9
|
+
# or
|
|
10
|
+
pnpm add @paykit-sdk/chapa
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { chapa } from '@paykit-sdk/chapa';
|
|
17
|
+
import { createEndpointHandlers, PayKit } from '@paykit-sdk/core';
|
|
18
|
+
|
|
19
|
+
export const paykit = new PayKit(chapa());
|
|
20
|
+
export const endpoints = createEndpointHandlers(paykit);
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Or with direct config:
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { createChapa } from '@paykit-sdk/chapa';
|
|
27
|
+
import { PayKit } from '@paykit-sdk/core';
|
|
28
|
+
|
|
29
|
+
export const paykit = new PayKit(
|
|
30
|
+
createChapa({
|
|
31
|
+
secretKey: 'CHASECK_TEST-...',
|
|
32
|
+
isSandbox: true,
|
|
33
|
+
}),
|
|
34
|
+
);
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Environment Variables
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
CHAPA_SECRET_KEY=CHASECK_TEST-...
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`isSandbox` is inferred from `NODE_ENV` — set `NODE_ENV=production` for live mode. Whether requests actually hit test or live data is determined by whether `CHAPA_SECRET_KEY` is a `CHASECK_TEST-` or `CHASECK-` key, not by `isSandbox` itself.
|
|
44
|
+
|
|
45
|
+
## Next.js API Route
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
// app/api/paykit/[...endpoint]/route.ts
|
|
49
|
+
import { endpoints } from '@/lib/paykit';
|
|
50
|
+
import { EndpointPath } from '@paykit-sdk/core';
|
|
51
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
52
|
+
|
|
53
|
+
export async function POST(
|
|
54
|
+
request: NextRequest,
|
|
55
|
+
{ params }: { params: Promise<{ endpoint: string[] }> },
|
|
56
|
+
) {
|
|
57
|
+
const { endpoint: endpointArray } = await params;
|
|
58
|
+
const endpoint = ('/' + endpointArray.join('/')) as EndpointPath;
|
|
59
|
+
const handler = endpoints[endpoint];
|
|
60
|
+
|
|
61
|
+
if (!handler) {
|
|
62
|
+
return NextResponse.json(
|
|
63
|
+
{ message: 'Not found' },
|
|
64
|
+
{ status: 404 },
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const { args } = await request.json();
|
|
69
|
+
const result = await handler(...args);
|
|
70
|
+
return NextResponse.json({ result });
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Webhooks
|
|
75
|
+
|
|
76
|
+
Chapa sends signed POST requests, using your secret key as the webhook secret — there is no separate webhook signing secret to configure.
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
// app/api/paykit/webhooks/route.ts
|
|
80
|
+
import { paykit } from '@/lib/paykit';
|
|
81
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
82
|
+
|
|
83
|
+
export async function POST(request: NextRequest) {
|
|
84
|
+
const body = await request.text();
|
|
85
|
+
|
|
86
|
+
const webhook = paykit.webhooks
|
|
87
|
+
.setup({ webhookSecret: process.env.CHAPA_SECRET_KEY! })
|
|
88
|
+
.on('payment.updated', async event => {
|
|
89
|
+
/* charge.success */
|
|
90
|
+
})
|
|
91
|
+
.on('payment.failed', async event => {
|
|
92
|
+
/* charge.failed/cancelled */
|
|
93
|
+
})
|
|
94
|
+
.on('invoice.generated', async event => {
|
|
95
|
+
/* charge.success */
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
await webhook.handle({
|
|
99
|
+
body,
|
|
100
|
+
headersAsObject: Object.fromEntries(request.headers),
|
|
101
|
+
fullUrl: request.url,
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
return NextResponse.json({ received: true });
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Checkout
|
|
109
|
+
|
|
110
|
+
Chapa requires an email customer and amount/currency in `provider_metadata`:
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
const checkout = await paykit.checkouts.create({
|
|
114
|
+
customer: { email: 'user@example.com' },
|
|
115
|
+
item_id: 'plan_pro',
|
|
116
|
+
session_type: 'one_time',
|
|
117
|
+
quantity: 1,
|
|
118
|
+
success_url: 'https://example.com/success',
|
|
119
|
+
cancel_url: 'https://example.com/cancel',
|
|
120
|
+
provider_metadata: {
|
|
121
|
+
amount: '400',
|
|
122
|
+
currency: 'ETB',
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
// Redirect user to checkout.payment_url
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Refunds
|
|
130
|
+
|
|
131
|
+
Refunds are always sent with an explicit `amount` — pass the full transaction amount for a full refund.
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
const refund = await paykit.refunds.create({
|
|
135
|
+
payment_id: 'tx_ref_from_the_original_transaction',
|
|
136
|
+
amount: 400,
|
|
137
|
+
reason: 'requested_by_customer',
|
|
138
|
+
metadata: null,
|
|
139
|
+
});
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Unsupported
|
|
143
|
+
|
|
144
|
+
Chapa has no customer management API and no subscription/plan API — `createCustomer`, `createSubscription`, and related methods throw `ProviderNotSupportedError`. Customer details are captured inline with each transaction instead.
|
|
145
|
+
|
|
146
|
+
## Documentation
|
|
147
|
+
|
|
148
|
+
Full docs at [docs.usepaykit.com/providers/chapa](https://docs.usepaykit.com/providers/chapa).
|
|
149
|
+
|
|
150
|
+
## Support
|
|
151
|
+
|
|
152
|
+
- [Chapa Documentation](https://developer.chapa.co)
|
|
153
|
+
- [PayKit Issues](https://github.com/usepaykit/paykit-sdk/issues)
|
|
154
|
+
|
|
155
|
+
## License
|
|
156
|
+
|
|
157
|
+
ISC
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { PaykitProviderOptions, AbstractPayKitProvider, PayKitProvider, ProviderMetadataRegistry, CreateCheckoutSchema, Checkout, UpdateCheckoutSchema, CreateCustomerParams, Customer, UpdateCustomerParams, CreateSubscriptionSchema, Subscription, UpdateSubscriptionSchema, CreatePaymentSchema, Payment, UpdatePaymentSchema, CapturePaymentSchema, CreateRefundSchema, Refund, WebhookHandlerConfig, WebhookEventPayload } from '@paykit-sdk/core';
|
|
2
|
+
import { ChapaRawEvents } from './schema.mjs';
|
|
3
|
+
|
|
4
|
+
interface ChapaMetadata extends ProviderMetadataRegistry {
|
|
5
|
+
refund: {
|
|
6
|
+
reference?: string;
|
|
7
|
+
};
|
|
8
|
+
checkout?: {
|
|
9
|
+
amount?: string;
|
|
10
|
+
currency?: string;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
interface ChapaOptions extends PaykitProviderOptions {
|
|
14
|
+
/**
|
|
15
|
+
* Chapa secret key
|
|
16
|
+
*/
|
|
17
|
+
secretKey: string;
|
|
18
|
+
}
|
|
19
|
+
declare class ChapaProvider extends AbstractPayKitProvider implements PayKitProvider<ChapaMetadata, null, ChapaRawEvents> {
|
|
20
|
+
readonly providerName = "chapa";
|
|
21
|
+
private readonly _client;
|
|
22
|
+
private readonly opts;
|
|
23
|
+
readonly isSandbox: boolean;
|
|
24
|
+
constructor(opts: ChapaOptions);
|
|
25
|
+
get _native(): null;
|
|
26
|
+
private unwrap;
|
|
27
|
+
/**
|
|
28
|
+
* Chapa has one way to charge a customer: POST /transaction/initialize.
|
|
29
|
+
* createCheckout and createPayment both boil down to this same call -
|
|
30
|
+
* only the input validation and the response mapper differ.
|
|
31
|
+
*/
|
|
32
|
+
private initializeTransaction;
|
|
33
|
+
createCheckout: (params: CreateCheckoutSchema<ChapaMetadata["checkout"]>) => Promise<Checkout>;
|
|
34
|
+
retrieveCheckout: (id: string) => Promise<Checkout | null>;
|
|
35
|
+
updateCheckout: (_id: string, _params: UpdateCheckoutSchema<ChapaMetadata["checkout"]>) => Promise<Checkout>;
|
|
36
|
+
deleteCheckout: (id: string) => Promise<null>;
|
|
37
|
+
createCustomer: (_params: CreateCustomerParams<ChapaMetadata["customer"]>) => Promise<Customer>;
|
|
38
|
+
retrieveCustomer: (_id: string) => Promise<Customer | null>;
|
|
39
|
+
updateCustomer: (_id: string, _params: UpdateCustomerParams<ChapaMetadata["customer"]>) => Promise<Customer>;
|
|
40
|
+
deleteCustomer: (_id: string) => Promise<null>;
|
|
41
|
+
createSubscription: (_params: CreateSubscriptionSchema<ChapaMetadata["subscription"]>) => Promise<Subscription>;
|
|
42
|
+
retrieveSubscription: (_id: string) => Promise<Subscription | null>;
|
|
43
|
+
updateSubscription: (_id: string, _params: UpdateSubscriptionSchema<ChapaMetadata["subscription"]>) => Promise<Subscription>;
|
|
44
|
+
cancelSubscription: (_id: string) => Promise<Subscription>;
|
|
45
|
+
deleteSubscription: (_id: string) => Promise<null>;
|
|
46
|
+
createPayment: (params: CreatePaymentSchema<ChapaMetadata["payment"]>) => Promise<Payment>;
|
|
47
|
+
retrievePayment: (id: string) => Promise<Payment | null>;
|
|
48
|
+
updatePayment: (_id: string, _params: UpdatePaymentSchema<ChapaMetadata["payment"]>) => Promise<Payment>;
|
|
49
|
+
deletePayment: (_id: string) => Promise<null>;
|
|
50
|
+
capturePayment: (_id: string, _params: CapturePaymentSchema) => Promise<Payment>;
|
|
51
|
+
cancelPayment: (id: string) => Promise<Payment>;
|
|
52
|
+
createRefund: (params: CreateRefundSchema<ChapaMetadata["refund"]>) => Promise<Refund>;
|
|
53
|
+
handleWebhook: (payload: WebhookHandlerConfig, webhookSecret: string | null) => Promise<Array<WebhookEventPayload<ChapaRawEvents>>>;
|
|
54
|
+
private safeHexEqual;
|
|
55
|
+
private mapToStandardEvents;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export { type ChapaOptions, ChapaProvider };
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { PaykitProviderOptions, AbstractPayKitProvider, PayKitProvider, ProviderMetadataRegistry, CreateCheckoutSchema, Checkout, UpdateCheckoutSchema, CreateCustomerParams, Customer, UpdateCustomerParams, CreateSubscriptionSchema, Subscription, UpdateSubscriptionSchema, CreatePaymentSchema, Payment, UpdatePaymentSchema, CapturePaymentSchema, CreateRefundSchema, Refund, WebhookHandlerConfig, WebhookEventPayload } from '@paykit-sdk/core';
|
|
2
|
+
import { ChapaRawEvents } from './schema.js';
|
|
3
|
+
|
|
4
|
+
interface ChapaMetadata extends ProviderMetadataRegistry {
|
|
5
|
+
refund: {
|
|
6
|
+
reference?: string;
|
|
7
|
+
};
|
|
8
|
+
checkout?: {
|
|
9
|
+
amount?: string;
|
|
10
|
+
currency?: string;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
interface ChapaOptions extends PaykitProviderOptions {
|
|
14
|
+
/**
|
|
15
|
+
* Chapa secret key
|
|
16
|
+
*/
|
|
17
|
+
secretKey: string;
|
|
18
|
+
}
|
|
19
|
+
declare class ChapaProvider extends AbstractPayKitProvider implements PayKitProvider<ChapaMetadata, null, ChapaRawEvents> {
|
|
20
|
+
readonly providerName = "chapa";
|
|
21
|
+
private readonly _client;
|
|
22
|
+
private readonly opts;
|
|
23
|
+
readonly isSandbox: boolean;
|
|
24
|
+
constructor(opts: ChapaOptions);
|
|
25
|
+
get _native(): null;
|
|
26
|
+
private unwrap;
|
|
27
|
+
/**
|
|
28
|
+
* Chapa has one way to charge a customer: POST /transaction/initialize.
|
|
29
|
+
* createCheckout and createPayment both boil down to this same call -
|
|
30
|
+
* only the input validation and the response mapper differ.
|
|
31
|
+
*/
|
|
32
|
+
private initializeTransaction;
|
|
33
|
+
createCheckout: (params: CreateCheckoutSchema<ChapaMetadata["checkout"]>) => Promise<Checkout>;
|
|
34
|
+
retrieveCheckout: (id: string) => Promise<Checkout | null>;
|
|
35
|
+
updateCheckout: (_id: string, _params: UpdateCheckoutSchema<ChapaMetadata["checkout"]>) => Promise<Checkout>;
|
|
36
|
+
deleteCheckout: (id: string) => Promise<null>;
|
|
37
|
+
createCustomer: (_params: CreateCustomerParams<ChapaMetadata["customer"]>) => Promise<Customer>;
|
|
38
|
+
retrieveCustomer: (_id: string) => Promise<Customer | null>;
|
|
39
|
+
updateCustomer: (_id: string, _params: UpdateCustomerParams<ChapaMetadata["customer"]>) => Promise<Customer>;
|
|
40
|
+
deleteCustomer: (_id: string) => Promise<null>;
|
|
41
|
+
createSubscription: (_params: CreateSubscriptionSchema<ChapaMetadata["subscription"]>) => Promise<Subscription>;
|
|
42
|
+
retrieveSubscription: (_id: string) => Promise<Subscription | null>;
|
|
43
|
+
updateSubscription: (_id: string, _params: UpdateSubscriptionSchema<ChapaMetadata["subscription"]>) => Promise<Subscription>;
|
|
44
|
+
cancelSubscription: (_id: string) => Promise<Subscription>;
|
|
45
|
+
deleteSubscription: (_id: string) => Promise<null>;
|
|
46
|
+
createPayment: (params: CreatePaymentSchema<ChapaMetadata["payment"]>) => Promise<Payment>;
|
|
47
|
+
retrievePayment: (id: string) => Promise<Payment | null>;
|
|
48
|
+
updatePayment: (_id: string, _params: UpdatePaymentSchema<ChapaMetadata["payment"]>) => Promise<Payment>;
|
|
49
|
+
deletePayment: (_id: string) => Promise<null>;
|
|
50
|
+
capturePayment: (_id: string, _params: CapturePaymentSchema) => Promise<Payment>;
|
|
51
|
+
cancelPayment: (id: string) => Promise<Payment>;
|
|
52
|
+
createRefund: (params: CreateRefundSchema<ChapaMetadata["refund"]>) => Promise<Refund>;
|
|
53
|
+
handleWebhook: (payload: WebhookHandlerConfig, webhookSecret: string | null) => Promise<Array<WebhookEventPayload<ChapaRawEvents>>>;
|
|
54
|
+
private safeHexEqual;
|
|
55
|
+
private mapToStandardEvents;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export { type ChapaOptions, ChapaProvider };
|