@afriex/sdk 4.1.0 → 5.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/README.md +19 -1
- package/dist/index.d.ts +20 -6
- package/dist/index.js +18 -2
- package/dist/version.d.ts +8 -0
- package/dist/version.js +8 -0
- package/package.json +29 -13
- package/skills/afriex-go-live/SKILL.md +62 -5
- package/skills/afriex-sdk/SKILL.md +5 -1
package/README.md
CHANGED
|
@@ -72,6 +72,7 @@ const session = await afriex.checkout.createSession({
|
|
|
72
72
|
currency: "USD",
|
|
73
73
|
merchantReference: "order-123",
|
|
74
74
|
redirectUrl: "https://example.com/checkout/complete",
|
|
75
|
+
channels: ["VIRTUAL_BANK_ACCOUNT", "MOBILE_MONEY", "CARD"],
|
|
75
76
|
customer: {
|
|
76
77
|
name: "John Doe",
|
|
77
78
|
email: "john@example.com",
|
|
@@ -79,7 +80,7 @@ const session = await afriex.checkout.createSession({
|
|
|
79
80
|
countryCode: "US",
|
|
80
81
|
},
|
|
81
82
|
});
|
|
82
|
-
// session.checkoutUrl
|
|
83
|
+
// session.checkoutUrl, session.channels
|
|
83
84
|
|
|
84
85
|
// Webhook verification (requires webhookPublicKey)
|
|
85
86
|
const isValid = afriex.webhooks.verify(payload, signature);
|
|
@@ -92,9 +93,12 @@ const isValid = afriex.webhooks.verify(payload, signature);
|
|
|
92
93
|
| `afriex.customers` | Customer CRUD, KYC updates, and document verification |
|
|
93
94
|
| `afriex.transactions` | Create, authorize, list, and track transactions |
|
|
94
95
|
| `afriex.paymentMethods` | Bank, mobile money, crypto wallets, virtual & pool accounts |
|
|
96
|
+
| `afriex.paymentBatches` | Pay many recipients in one call |
|
|
95
97
|
| `afriex.balance` | Organization wallet balances and sandbox top-ups |
|
|
96
98
|
| `afriex.rates` | Exchange rates and conversions |
|
|
97
99
|
| `afriex.checkout` | Hosted checkout sessions (card, virtual account, momo) |
|
|
100
|
+
| `afriex.media` | Upload invoices, payment proofs and documents |
|
|
101
|
+
| `afriex.smeRegistration` | Register the business for dedicated KES virtual accounts |
|
|
98
102
|
| `afriex.webhooks` | Webhook signature verification and sandbox test triggers |
|
|
99
103
|
|
|
100
104
|
Every service is always available on the client. `afriex.webhooks.verify()` returns `false`
|
|
@@ -114,10 +118,21 @@ interface AfriexSDKConfig {
|
|
|
114
118
|
maxRetries: number;
|
|
115
119
|
retryDelay: number;
|
|
116
120
|
retryableStatusCodes: number[]; // Default: [408, 429, 500, 502, 503, 504]
|
|
121
|
+
retryableMethods?: HttpMethod[]; // Default: every method except POST and PATCH
|
|
117
122
|
};
|
|
123
|
+
apiVersion?: string; // Default: '2026-05-18', sent as x-api-version
|
|
124
|
+
signRequest?: RequestSigner; // Optional - returns the x-api-signature value
|
|
125
|
+
userAgent?: string; // Default: 'Afriex-TypeScript-SDK/<version of @afriex/sdk>'
|
|
118
126
|
}
|
|
119
127
|
```
|
|
120
128
|
|
|
129
|
+
`SDK_VERSION` holds the version of `@afriex/sdk` that is installed.
|
|
130
|
+
|
|
131
|
+
Retries are off by default. When they are on, `POST` and `PATCH` requests are
|
|
132
|
+
still sent once unless `retryableMethods` lists them. See
|
|
133
|
+
[`@afriex/core`](https://www.npmjs.com/package/@afriex/core) for retries and
|
|
134
|
+
request signing.
|
|
135
|
+
|
|
121
136
|
`staging` points at `https://sandbox.api.afriex.com/api/v1`, `production` at
|
|
122
137
|
`https://api.afriex.com/api/v1`.
|
|
123
138
|
|
|
@@ -153,9 +168,12 @@ For smaller bundle sizes, install packages individually:
|
|
|
153
168
|
| `@afriex/customers` | Customer management and KYC |
|
|
154
169
|
| `@afriex/transactions` | Transaction handling |
|
|
155
170
|
| `@afriex/payment-methods` | Payment methods, institutions, virtual & pool accounts |
|
|
171
|
+
| `@afriex/payment-batches` | Bulk payouts to a saved list of recipients |
|
|
156
172
|
| `@afriex/balance` | Balance queries and sandbox top-ups |
|
|
157
173
|
| `@afriex/rates` | Exchange rates and conversions |
|
|
158
174
|
| `@afriex/checkout` | Hosted checkout sessions |
|
|
175
|
+
| `@afriex/media` | File uploads |
|
|
176
|
+
| `@afriex/sme-registration` | SME registration for KES virtual accounts |
|
|
159
177
|
| `@afriex/webhooks` | Webhook verification and test triggers |
|
|
160
178
|
|
|
161
179
|
Each service package depends only on `@afriex/core`, so you can mix and match.
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,9 @@ import { BalanceService } from "@afriex/balance";
|
|
|
6
6
|
import { RateService } from "@afriex/rates";
|
|
7
7
|
import { CheckoutService } from "@afriex/checkout";
|
|
8
8
|
import { WebhookService } from "@afriex/webhooks";
|
|
9
|
+
import { MediaService } from "@afriex/media";
|
|
10
|
+
import { PaymentBatchService } from "@afriex/payment-batches";
|
|
11
|
+
import { SmeRegistrationService } from "@afriex/sme-registration";
|
|
9
12
|
export interface AfriexSDKConfig extends AfriexConfig {
|
|
10
13
|
webhookPublicKey?: string;
|
|
11
14
|
}
|
|
@@ -13,14 +16,18 @@ export declare class AfriexSDK extends AfriexClient {
|
|
|
13
16
|
readonly customers: CustomerService;
|
|
14
17
|
readonly transactions: TransactionService;
|
|
15
18
|
readonly paymentMethods: PaymentMethodService;
|
|
19
|
+
readonly paymentBatches: PaymentBatchService;
|
|
16
20
|
readonly balance: BalanceService;
|
|
17
21
|
readonly rates: RateService;
|
|
18
22
|
readonly checkout: CheckoutService;
|
|
23
|
+
readonly media: MediaService;
|
|
24
|
+
readonly smeRegistration: SmeRegistrationService;
|
|
19
25
|
readonly webhooks: WebhookService;
|
|
20
26
|
readonly webhookVerifier?: WebhookService;
|
|
21
27
|
constructor(config: AfriexSDKConfig);
|
|
22
28
|
}
|
|
23
29
|
export { AfriexSDK as Afriex };
|
|
30
|
+
export { SDK_VERSION } from "./version.js";
|
|
24
31
|
export * from "@afriex/core";
|
|
25
32
|
export { CustomerService } from "@afriex/customers";
|
|
26
33
|
export { TransactionService } from "@afriex/transactions";
|
|
@@ -29,12 +36,19 @@ export { BalanceService } from "@afriex/balance";
|
|
|
29
36
|
export { RateService } from "@afriex/rates";
|
|
30
37
|
export { CheckoutService } from "@afriex/checkout";
|
|
31
38
|
export { WebhookVerifier, WebhookService } from "@afriex/webhooks";
|
|
32
|
-
export
|
|
33
|
-
export
|
|
34
|
-
export
|
|
35
|
-
export type {
|
|
39
|
+
export { MediaService } from "@afriex/media";
|
|
40
|
+
export { PaymentBatchService } from "@afriex/payment-batches";
|
|
41
|
+
export { SmeRegistrationService } from "@afriex/sme-registration";
|
|
42
|
+
export type { Customer, CustomerKyc, CustomerMeta, KycDocumentType, UpdatableKycDocumentType, ReadOnlyKycDocumentType, CreateCustomerRequest, UpdateCustomerRequest, UpdateCustomerKycRequest, VerifyCustomerRequest, ListCustomersParams, CustomerListResponse, } from "@afriex/customers";
|
|
43
|
+
export type { Transaction, CreateTransactionRequest, CreateWithdrawTransaction, CreateDepositTransaction, CreateSwapTransaction, TransactionAmount, TransactionAmounts, SwapAmount, AuthorizeTransactionRequest, SimulateTransactionRequest, SimulateTransactionOutcome, SettlementAdvice, SubmitPoolAccountProofRequest, PoolAccountProofSender, ListTransactionsParams, TransactionListResponse, TransactionListType, TransactionListStatus, TransactionSettlement, TransactionChannel, TransactionType, TransactionMeta, TransactionMetaResponse, TransactionFailureCode, TransactionFailureReason, } from "@afriex/transactions";
|
|
44
|
+
export type { PaymentMethod, PaymentMethodBankAddress, PaymentMethodInstitution, PaymentMethodRecipient, PaymentMethodTransaction, CreatePaymentMethodRequest, CreateInstitutionPaymentMethodRequest, CreateAliasPaymentMethodRequest, CreateVirtualBankAccountPaymentMethodRequest, AliasPaymentChannel, InstitutionPaymentChannel, ListPaymentMethodsParams, PaymentMethodListResponse, PaymentMethodListChannel, PaymentMethodListStatus, PaymentMethodListCapability, VirtualAccountLabel, PaymentChannel, CreatablePaymentChannel, PaymentMethodStatus, CardBrand, CardExpiration, Institution, InstitutionListResponse, InstitutionListChannel, InstitutionCode, InstitutionCodesParams, InstitutionCodesResponse, ResolveAccountParams, ResolvedAccount, ResolveAccountResponse, GetInstitutionsParams, CryptoWallet, CryptoWalletData, CryptoWalletResponse, GetCryptoWalletParams, ListVirtualAccountsParams, CreateVirtualAccountParams, ListPoolAccountsParams, VirtualAccountListResponse, PoolAccountResponse, SimulateTransferRequest, SimulateTransferResult, } from "@afriex/payment-methods";
|
|
45
|
+
export type { BalanceResponse, GetBalanceParams, TopUpParams, TopUpResponse, TopUpTransaction, TopUpTransactionType, TopUpTransactionStatus, } from "@afriex/balance";
|
|
36
46
|
export type { RatesResponse, GetRatesParams } from "@afriex/rates";
|
|
37
|
-
export type { CheckoutSession, CreateCheckoutSessionRequest, CheckoutCustomer, CheckoutChannel, } from "@afriex/checkout";
|
|
38
|
-
export type {
|
|
47
|
+
export type { CheckoutSession, CreateCheckoutSessionRequest, CreateCheckoutSessionResponse, CheckoutCustomer, CheckoutChannel, } from "@afriex/checkout";
|
|
48
|
+
export type { MediaUploadType, CreateUploadUrlRequest, UploadUrl, UploadableFile, UploadFileRequest, UploadedFile, } from "@afriex/media";
|
|
49
|
+
export type { PaymentBatch, PaymentBatchRequest, PaymentBatchSource, PaymentBatchFundingMethod, PaymentBatchListItem, PaymentBatchListParams, PaymentBatchListResponse, PaymentBatchInstitution, PaymentBatchAmount, PaymentBatchRecipientRequest, UpdatePaymentBatchRecipientRequest, SavedPaymentBatchRecipient, PaymentBatchRecipient, PaymentBatchRecipientListResponse, PaymentBatchOutcomes, WithdrawPaymentBatchParams, PaymentBatchSession, PaymentBatchSessionResult, PaymentBatchSessionListResponse, } from "@afriex/payment-batches";
|
|
50
|
+
export type { SmeRegistration, SmeRegistrationRequest, SmeRegistrationStep, SmeRegistrationStatus, SmeRegistrationStatusResult, SmeReviewStatus, SmeBusinessType, InitiateSmeRegistrationData, ConfirmSmeRegistrationOtpData, SubmitSmeRegistrationData, } from "@afriex/sme-registration";
|
|
51
|
+
export type { WebhookPayload, CustomerWebhookPayload, CustomerEventType, CustomerWebhookData, PaymentMethodWebhookPayload, PaymentMethodEventType, PaymentMethodWebhookData, TransactionWebhookPayload, TransactionEventType, TransactionWebhookData, TransactionWebhookMeta, TransactionWebhookFailureReason, TransactionWebhookStatus, CheckoutSessionWebhookPayload, CheckoutSessionEventType, CheckoutSessionWebhookData, CheckoutSessionWebhookCustomer, PoolDepositRequestWebhookPayload, PoolDepositRequestEventType, PoolDepositRejectedWebhookData, TriggerWebhookRequest, TriggerWebhookResult, TriggerWebhookResponse, WebhookEventType, TriggerableWebhookEventType, WebhookEnvelope, } from "@afriex/webhooks";
|
|
39
52
|
export { WEBHOOK_SIGNATURE_HEADER } from "@afriex/webhooks";
|
|
53
|
+
export { TransactionStatus, DEFAULT_TRANSACTION_TYPE, } from "@afriex/transactions";
|
|
40
54
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { AfriexClient } from "@afriex/core";
|
|
1
|
+
import { AfriexClient, DEFAULT_USER_AGENT, } from "@afriex/core";
|
|
2
|
+
import { SDK_VERSION } from "./version.js";
|
|
2
3
|
import { CustomerService } from "@afriex/customers";
|
|
3
4
|
import { TransactionService } from "@afriex/transactions";
|
|
4
5
|
import { PaymentMethodService } from "@afriex/payment-methods";
|
|
@@ -6,16 +7,25 @@ import { BalanceService } from "@afriex/balance";
|
|
|
6
7
|
import { RateService } from "@afriex/rates";
|
|
7
8
|
import { CheckoutService } from "@afriex/checkout";
|
|
8
9
|
import { WebhookService } from "@afriex/webhooks";
|
|
10
|
+
import { MediaService } from "@afriex/media";
|
|
11
|
+
import { PaymentBatchService } from "@afriex/payment-batches";
|
|
12
|
+
import { SmeRegistrationService } from "@afriex/sme-registration";
|
|
9
13
|
export class AfriexSDK extends AfriexClient {
|
|
10
14
|
constructor(config) {
|
|
11
|
-
super(
|
|
15
|
+
super({
|
|
16
|
+
...config,
|
|
17
|
+
userAgent: config.userAgent || `${DEFAULT_USER_AGENT}/${SDK_VERSION}`,
|
|
18
|
+
});
|
|
12
19
|
const httpClient = this.getHttpClient();
|
|
13
20
|
this.customers = new CustomerService(httpClient);
|
|
14
21
|
this.transactions = new TransactionService(httpClient);
|
|
15
22
|
this.paymentMethods = new PaymentMethodService(httpClient);
|
|
23
|
+
this.paymentBatches = new PaymentBatchService(httpClient);
|
|
16
24
|
this.balance = new BalanceService(httpClient);
|
|
17
25
|
this.rates = new RateService(httpClient);
|
|
18
26
|
this.checkout = new CheckoutService(httpClient);
|
|
27
|
+
this.media = new MediaService(httpClient);
|
|
28
|
+
this.smeRegistration = new SmeRegistrationService(httpClient);
|
|
19
29
|
this.webhooks = new WebhookService(httpClient, config.webhookPublicKey);
|
|
20
30
|
if (config.webhookPublicKey) {
|
|
21
31
|
this.webhookVerifier = this.webhooks;
|
|
@@ -24,6 +34,7 @@ export class AfriexSDK extends AfriexClient {
|
|
|
24
34
|
}
|
|
25
35
|
// Short alias
|
|
26
36
|
export { AfriexSDK as Afriex };
|
|
37
|
+
export { SDK_VERSION } from "./version.js";
|
|
27
38
|
// Re-export core types
|
|
28
39
|
export * from "@afriex/core";
|
|
29
40
|
// Re-export service classes explicitly to avoid conflicts
|
|
@@ -34,5 +45,10 @@ export { BalanceService } from "@afriex/balance";
|
|
|
34
45
|
export { RateService } from "@afriex/rates";
|
|
35
46
|
export { CheckoutService } from "@afriex/checkout";
|
|
36
47
|
export { WebhookVerifier, WebhookService } from "@afriex/webhooks";
|
|
48
|
+
export { MediaService } from "@afriex/media";
|
|
49
|
+
export { PaymentBatchService } from "@afriex/payment-batches";
|
|
50
|
+
export { SmeRegistrationService } from "@afriex/sme-registration";
|
|
37
51
|
export { WEBHOOK_SIGNATURE_HEADER } from "@afriex/webhooks";
|
|
52
|
+
// `TransactionStatus` is a value as well as a type, so it is exported as both.
|
|
53
|
+
export { TransactionStatus, DEFAULT_TRANSACTION_TYPE, } from "@afriex/transactions";
|
|
38
54
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The version of `@afriex/sdk`, sent in the `User-Agent` header.
|
|
3
|
+
*
|
|
4
|
+
* Kept equal to the version in package.json by `scripts/sync-sdk-version.mjs`,
|
|
5
|
+
* which runs as part of `pnpm run version`. Do not edit it by hand.
|
|
6
|
+
*/
|
|
7
|
+
export declare const SDK_VERSION = "5.1.0";
|
|
8
|
+
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The version of `@afriex/sdk`, sent in the `User-Agent` header.
|
|
3
|
+
*
|
|
4
|
+
* Kept equal to the version in package.json by `scripts/sync-sdk-version.mjs`,
|
|
5
|
+
* which runs as part of `pnpm run version`. Do not edit it by hand.
|
|
6
|
+
*/
|
|
7
|
+
export const SDK_VERSION = "5.1.0";
|
|
8
|
+
//# sourceMappingURL=version.js.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@afriex/sdk",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Official TypeScript SDK for the Afriex Business API",
|
|
3
|
+
"version": "5.1.0",
|
|
4
|
+
"description": "Official TypeScript SDK for the Afriex Business API: cross-border payouts, collections, virtual accounts, exchange rates and webhooks",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -20,14 +20,17 @@
|
|
|
20
20
|
}
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@afriex/
|
|
24
|
-
"@afriex/
|
|
25
|
-
"@afriex/
|
|
26
|
-
"@afriex/
|
|
27
|
-
"@afriex/
|
|
28
|
-
"@afriex/rates": "2.0.
|
|
29
|
-
"@afriex/checkout": "3.0
|
|
30
|
-
"@afriex/
|
|
23
|
+
"@afriex/customers": "4.0.0",
|
|
24
|
+
"@afriex/transactions": "3.0.0",
|
|
25
|
+
"@afriex/payment-methods": "5.0.0",
|
|
26
|
+
"@afriex/balance": "2.1.0",
|
|
27
|
+
"@afriex/core": "2.2.0",
|
|
28
|
+
"@afriex/rates": "2.0.2",
|
|
29
|
+
"@afriex/checkout": "3.1.0",
|
|
30
|
+
"@afriex/payment-batches": "1.0.0",
|
|
31
|
+
"@afriex/webhooks": "3.1.0",
|
|
32
|
+
"@afriex/media": "1.0.0",
|
|
33
|
+
"@afriex/sme-registration": "1.0.0"
|
|
31
34
|
},
|
|
32
35
|
"devDependencies": {
|
|
33
36
|
"@tanstack/intent": "^0.3.6",
|
|
@@ -48,12 +51,25 @@
|
|
|
48
51
|
},
|
|
49
52
|
"keywords": [
|
|
50
53
|
"afriex",
|
|
51
|
-
"sdk",
|
|
52
|
-
"api",
|
|
53
|
-
"money-transfer",
|
|
54
54
|
"payments",
|
|
55
55
|
"fintech",
|
|
56
|
+
"africa",
|
|
57
|
+
"cross-border-payments",
|
|
56
58
|
"typescript",
|
|
59
|
+
"afriex-sdk",
|
|
60
|
+
"sdk",
|
|
61
|
+
"api",
|
|
62
|
+
"payments-api",
|
|
63
|
+
"api-client",
|
|
64
|
+
"money-transfer",
|
|
65
|
+
"remittance",
|
|
66
|
+
"payouts",
|
|
67
|
+
"mobile-money",
|
|
68
|
+
"bank-transfer",
|
|
69
|
+
"nigeria",
|
|
70
|
+
"kenya",
|
|
71
|
+
"ghana",
|
|
72
|
+
"nodejs",
|
|
57
73
|
"tanstack-intent"
|
|
58
74
|
],
|
|
59
75
|
"license": "MIT",
|
|
@@ -90,8 +90,24 @@ export const afriex = new AfriexSDK({
|
|
|
90
90
|
|
|
91
91
|
Fail condition: no `retryConfig` — `DEFAULT_CONFIG` sets `maxRetries: 0`, so a
|
|
92
92
|
single 503 fails the request outright.
|
|
93
|
-
Fix: supply `retryConfig
|
|
94
|
-
|
|
93
|
+
Fix: supply `retryConfig`.
|
|
94
|
+
|
|
95
|
+
### Check: writes are not retried blindly
|
|
96
|
+
|
|
97
|
+
Expected: `retryConfig.retryableMethods` is absent, or lists neither `POST`
|
|
98
|
+
nor `PATCH`.
|
|
99
|
+
|
|
100
|
+
With the default methods, the SDK retries reads and sends every `POST` and
|
|
101
|
+
`PATCH` once. A write that fails with a 5xx or a timeout may still have been
|
|
102
|
+
applied, so the application reads the state back (for a transaction,
|
|
103
|
+
`transactions.list({ reference })`) before it sends the write again, and
|
|
104
|
+
reuses the same `meta.idempotencyKey` when it does.
|
|
105
|
+
|
|
106
|
+
Fail condition: `retryableMethods` includes `POST` on a client that calls
|
|
107
|
+
`paymentBatches.withdraw` — a repeat starts a second run and pays every
|
|
108
|
+
recipient again.
|
|
109
|
+
Fix: remove `POST` from `retryableMethods` and retry writes in application
|
|
110
|
+
code, where the state can be checked first.
|
|
95
111
|
|
|
96
112
|
### Check: request logging does not leak request bodies
|
|
97
113
|
|
|
@@ -188,12 +204,50 @@ export async function seedTestWallet(): Promise<void> {
|
|
|
188
204
|
}
|
|
189
205
|
```
|
|
190
206
|
|
|
191
|
-
Fail condition: `topUpSandbox
|
|
192
|
-
|
|
207
|
+
Fail condition: `balance.topUpSandbox`, `webhooks.triggerTestWebhook`,
|
|
208
|
+
`transactions.simulate` or `paymentMethods.simulateTransfer` reachable on a
|
|
209
|
+
production code path — all four answer `403 FORBIDDEN` there.
|
|
193
210
|
Fix: guard them behind an environment check or keep them in test-only modules.
|
|
194
211
|
|
|
212
|
+
### Check: no sandbox test value reaches production
|
|
213
|
+
|
|
214
|
+
Expected:
|
|
215
|
+
|
|
216
|
+
```ts
|
|
217
|
+
const SANDBOX_OUTCOME_SUFFIXES = ["0001", "0002", "0003", "0004", "0005"];
|
|
218
|
+
|
|
219
|
+
export function assertRealAccount(accountNumber: string): void {
|
|
220
|
+
if (process.env.NODE_ENV !== "production") {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
if (SANDBOX_OUTCOME_SUFFIXES.some((suffix) => accountNumber.endsWith(suffix))) {
|
|
224
|
+
console.warn("account number matches a sandbox test value", accountNumber);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
In the sandbox, an account number, phone number or card number ending in
|
|
230
|
+
`0001` to `0005` chooses the outcome of a transaction, the OTP is always
|
|
231
|
+
`123456`, and `SIMULATE_INSTANT` in `meta.reference` completes a transaction
|
|
232
|
+
early. None of this applies in production, where those are ordinary values.
|
|
233
|
+
|
|
234
|
+
Fail condition: a fixture account, the OTP `123456` or a `SIMULATE_INSTANT`
|
|
235
|
+
reference hard-coded on a path that runs in production.
|
|
236
|
+
Fix: keep test values in fixtures that only the test environment loads.
|
|
237
|
+
|
|
195
238
|
## Webhook Checks
|
|
196
239
|
|
|
240
|
+
### Check: the firewall admits Afriex's webhook addresses
|
|
241
|
+
|
|
242
|
+
Expected: inbound traffic to the webhook endpoint is allowed from
|
|
243
|
+
`34.197.33.100` in production and `34.234.189.210` in the sandbox.
|
|
244
|
+
|
|
245
|
+
Fail condition: a firewall or allowlist in front of the endpoint that does not
|
|
246
|
+
include the address for the environment — deliveries are dropped before they
|
|
247
|
+
reach the handler, and nothing is logged on the application side.
|
|
248
|
+
Fix: add the address to the allowlist. The address is not a substitute for
|
|
249
|
+
verifying the signature.
|
|
250
|
+
|
|
197
251
|
### Check: the endpoint verifies signatures against the raw body
|
|
198
252
|
|
|
199
253
|
Expected:
|
|
@@ -319,10 +373,13 @@ Source: packages/core/src/errors/ApiError.ts
|
|
|
319
373
|
- [ ] API key read from a secret store; no key in source or client bundles
|
|
320
374
|
- [ ] Separate sandbox and production keys; `environment` set explicitly
|
|
321
375
|
- [ ] `retryConfig` configured — retries are off by default
|
|
376
|
+
- [ ] `retryableMethods` does not include `POST` or `PATCH`
|
|
377
|
+
- [ ] Afriex's webhook IP address is allowed through the firewall
|
|
322
378
|
- [ ] `logLevel` is `LogLevel.ERROR` in production
|
|
323
379
|
- [ ] Every `transactions.create` carries a persisted, reused `meta.idempotencyKey`
|
|
324
380
|
- [ ] Order state settles on `TRANSACTION.UPDATED`, not on `create()` resolving
|
|
325
|
-
- [ ] `topUpSandbox` and `
|
|
381
|
+
- [ ] `topUpSandbox`, `triggerTestWebhook`, `simulate` and `simulateTransfer` are unreachable in production
|
|
382
|
+
- [ ] No sandbox test account, OTP or `SIMULATE_INSTANT` reference on a production path
|
|
326
383
|
- [ ] Webhook route uses a raw body parser and `verifyAndParse`
|
|
327
384
|
- [ ] `AFRIEX_WEBHOOK_PUBLIC_KEY` asserted at boot
|
|
328
385
|
- [ ] Webhook handlers deduplicate on `transactionId` plus `status`
|
|
@@ -3,7 +3,8 @@ name: afriex-sdk
|
|
|
3
3
|
description: >
|
|
4
4
|
Entry point for the Afriex Business API TypeScript SDK (@afriex/sdk) — the
|
|
5
5
|
AfriexSDK / Afriex facade and its customers, transactions, paymentMethods,
|
|
6
|
-
balance, rates, checkout,
|
|
6
|
+
paymentBatches, balance, rates, checkout, media, smeRegistration, and
|
|
7
|
+
webhooks services. Covers installation,
|
|
7
8
|
AfriexSDKConfig including webhookPublicKey, choosing sandbox vs production,
|
|
8
9
|
the end-to-end customer → payment method → transaction → webhook payout flow,
|
|
9
10
|
and which sub-skill covers each service. Load when starting an Afriex
|
|
@@ -58,9 +59,12 @@ import it where needed — each construction builds a fresh HTTP client.
|
|
|
58
59
|
| Register senders and recipients, submit KYC | `afriex.customers` | `afriex-customers` |
|
|
59
60
|
| Add bank, mobile money, or virtual account rails | `afriex.paymentMethods` | `afriex-payment-methods` |
|
|
60
61
|
| Send payouts, collect deposits, swap currencies | `afriex.transactions` | `afriex-transactions` |
|
|
62
|
+
| Pay many recipients in one call | `afriex.paymentBatches` | `afriex-payment-batches` |
|
|
61
63
|
| Read wallet balances, fund a sandbox wallet | `afriex.balance` | `afriex-balance` |
|
|
62
64
|
| Quote exchange rates | `afriex.rates` | `afriex-rates` |
|
|
63
65
|
| Host a payment page | `afriex.checkout` | `afriex-checkout` |
|
|
66
|
+
| Upload an invoice, a proof or a document | `afriex.media` | `afriex-media` |
|
|
67
|
+
| Register for dedicated KES virtual accounts | `afriex.smeRegistration` | `afriex-sme-registration` |
|
|
64
68
|
| Verify inbound events, replay test events | `afriex.webhooks` | `afriex-webhooks` |
|
|
65
69
|
| Configure transport, errors, retries | `AfriexClient`, errors | `afriex-core` |
|
|
66
70
|
| Ship to production safely | — | `afriex-go-live` |
|