@nokinc-flur/sdk 1.0.5 → 1.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/dist/index.cjs +1410 -633
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1684 -146
- package/dist/index.d.ts +1684 -146
- package/dist/index.js +1364 -633
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.cjs
CHANGED
|
@@ -26,11 +26,24 @@ __export(index_exports, {
|
|
|
26
26
|
AccountMembershipSchema: () => AccountMembershipSchema,
|
|
27
27
|
AccountSchema: () => AccountSchema,
|
|
28
28
|
ApiCredentialPublicSchema: () => ApiCredentialPublicSchema,
|
|
29
|
+
COLLECTION_INTENT_STATUSES: () => COLLECTION_INTENT_STATUSES,
|
|
30
|
+
COLLECTION_PAYMENT_STATUSES: () => COLLECTION_PAYMENT_STATUSES,
|
|
31
|
+
CUSTODIAL_MODES: () => CUSTODIAL_MODES,
|
|
32
|
+
CollectionIntentSchema: () => CollectionIntentSchema,
|
|
33
|
+
CollectionPaymentResultSchema: () => CollectionPaymentResultSchema,
|
|
34
|
+
CollectionPaymentSchema: () => CollectionPaymentSchema,
|
|
35
|
+
CollectionReportSummarySchema: () => CollectionReportSummarySchema,
|
|
36
|
+
CollectionStatementSchema: () => CollectionStatementSchema,
|
|
29
37
|
ConsumerOACRecordSchema: () => OACRecordSchema,
|
|
30
38
|
ConsumerOACSchema: () => ConsumerOACSchema,
|
|
31
39
|
ConsumerPaymentClaimSchema: () => ConsumerPaymentClaimSchema,
|
|
32
40
|
ConsumerSettleResultSchema: () => ConsumerSettleResultSchema,
|
|
33
41
|
ConsumerSettlementSchema: () => ConsumerSettlementSchema,
|
|
42
|
+
CreateCollectionIntentInputSchema: () => CreateCollectionIntentInputSchema,
|
|
43
|
+
CreatePayoutDestinationInputSchema: () => CreatePayoutDestinationInputSchema,
|
|
44
|
+
CreatePayoutInputSchema: () => CreatePayoutInputSchema,
|
|
45
|
+
CreateWithdrawalInputSchema: () => CreateWithdrawalInputSchema,
|
|
46
|
+
CreateWithdrawalResultSchema: () => CreateWithdrawalResultSchema,
|
|
34
47
|
DeviceKeyRecordSchema: () => DeviceKeyRecordSchema,
|
|
35
48
|
DisableOfflineInputSchema: () => DisableOfflineInputSchema,
|
|
36
49
|
DisableOfflineResultSchema: () => DisableOfflineResultSchema,
|
|
@@ -43,8 +56,14 @@ __export(index_exports, {
|
|
|
43
56
|
FlurError: () => FlurError,
|
|
44
57
|
FlurExpiredError: () => FlurExpiredError,
|
|
45
58
|
FlurReplayError: () => FlurReplayError,
|
|
59
|
+
IngestFundingResultSchema: () => IngestFundingResultSchema,
|
|
46
60
|
IssueOACInputSchema: () => IssueOACInputSchema,
|
|
61
|
+
ListPayoutDestinationsResultSchema: () => ListPayoutDestinationsResultSchema,
|
|
47
62
|
MEMBERSHIP_ROLES: () => MEMBERSHIP_ROLES,
|
|
63
|
+
MERCHANT_PAYOUT_STATUSES: () => MERCHANT_PAYOUT_STATUSES,
|
|
64
|
+
MERCHANT_PROFILE_STATUSES: () => MERCHANT_PROFILE_STATUSES,
|
|
65
|
+
MerchantPayoutSchema: () => MerchantPayoutSchema,
|
|
66
|
+
MerchantProfileSchema: () => MerchantProfileSchema,
|
|
48
67
|
MintedApiCredentialSchema: () => MintedApiCredentialSchema,
|
|
49
68
|
NGN_CURRENCY_CODE: () => NGN_CURRENCY_CODE,
|
|
50
69
|
NG_COUNTRY_CODE: () => NG_COUNTRY_CODE,
|
|
@@ -59,25 +78,46 @@ __export(index_exports, {
|
|
|
59
78
|
OfflineStateResultSchema: () => OfflineStateResultSchema,
|
|
60
79
|
OfflineStatusResultSchema: () => OfflineStatusResultSchema,
|
|
61
80
|
OfflineTokenSchema: () => OfflineTokenSchema,
|
|
81
|
+
PARTNER_FUNDING_DIRECTIONS: () => PARTNER_FUNDING_DIRECTIONS,
|
|
82
|
+
PARTNER_FUNDING_STATUSES: () => PARTNER_FUNDING_STATUSES,
|
|
83
|
+
PARTNER_KINDS: () => PARTNER_KINDS,
|
|
84
|
+
PARTNER_PROFILE_STATUSES: () => PARTNER_PROFILE_STATUSES,
|
|
62
85
|
PARTNER_SCOPES: () => PARTNER_SCOPES,
|
|
63
86
|
PASS_KINDS: () => PASS_KINDS,
|
|
64
87
|
PASS_STATES: () => PASS_STATES,
|
|
65
88
|
PAYLOAD_FORMAT_INDICATOR_VALUE: () => PAYLOAD_FORMAT_INDICATOR_VALUE,
|
|
89
|
+
PAYOUT_DESTINATION_STATUSES: () => PAYOUT_DESTINATION_STATUSES,
|
|
66
90
|
POINT_OF_INITIATION: () => POINT_OF_INITIATION,
|
|
91
|
+
PartnerFundingEventInputSchema: () => PartnerFundingEventInputSchema,
|
|
92
|
+
PartnerFundingSchema: () => PartnerFundingSchema,
|
|
93
|
+
PartnerProfileSchema: () => PartnerProfileSchema,
|
|
67
94
|
PassMetadataSchema: () => PassMetadataSchema,
|
|
68
95
|
PassSchema: () => PassSchema,
|
|
96
|
+
PayCollectionInputSchema: () => PayCollectionInputSchema,
|
|
69
97
|
PaymentClaimSchema: () => PaymentClaimSchema,
|
|
98
|
+
PayoutDestinationSchema: () => PayoutDestinationSchema,
|
|
99
|
+
PayoutEventInputSchema: () => PayoutEventInputSchema,
|
|
100
|
+
ProviderEventInputSchema: () => ProviderEventInputSchema,
|
|
101
|
+
ProviderEventRecordSchema: () => ProviderEventRecordSchema,
|
|
102
|
+
PublicCollectionIntentSchema: () => PublicCollectionIntentSchema,
|
|
70
103
|
RECEIPT_CHANNELS: () => RECEIPT_CHANNELS,
|
|
71
104
|
RECEIPT_KINDS: () => RECEIPT_KINDS,
|
|
72
105
|
REPLAY_WINDOW_MS: () => REPLAY_WINDOW_MS,
|
|
73
106
|
ReceiptPayloadSchema: () => ReceiptPayloadSchema,
|
|
74
107
|
ReceiptSchema: () => ReceiptSchema,
|
|
108
|
+
ReconciliationReportSchema: () => ReconciliationReportSchema,
|
|
109
|
+
RecordPayoutEventResultSchema: () => RecordPayoutEventResultSchema,
|
|
75
110
|
RedemptionSchema: () => RedemptionSchema,
|
|
76
111
|
RegisterDeviceKeyInputSchema: () => RegisterDeviceKeyInputSchema,
|
|
77
112
|
RevokeDeviceKeyInputSchema: () => RevokeDeviceKeyInputSchema,
|
|
113
|
+
SETTLEMENT_SCHEDULES: () => SETTLEMENT_SCHEDULES,
|
|
78
114
|
SettleResponseSchema: () => SettleResponseSchema,
|
|
79
115
|
SettlementSchema: () => SettlementSchema,
|
|
80
116
|
SignedConsumerOACSchema: () => SignedConsumerOACSchema,
|
|
117
|
+
UpsertMerchantProfileInputSchema: () => UpsertMerchantProfileInputSchema,
|
|
118
|
+
UpsertPartnerProfileInputSchema: () => UpsertPartnerProfileInputSchema,
|
|
119
|
+
WITHDRAWAL_STATES: () => WITHDRAWAL_STATES,
|
|
120
|
+
WithdrawalSchema: () => WithdrawalSchema,
|
|
81
121
|
bodySha256Hex: () => bodySha256Hex,
|
|
82
122
|
buildAuthorization: () => buildAuthorization,
|
|
83
123
|
buildOAC: () => buildOAC,
|
|
@@ -94,10 +134,16 @@ __export(index_exports, {
|
|
|
94
134
|
crc16ccittHex: () => crc16ccittHex,
|
|
95
135
|
createAccountsClient: () => createAccountsClient,
|
|
96
136
|
createApiCredentialsAdminClient: () => createApiCredentialsAdminClient,
|
|
137
|
+
createCollectionsClient: () => createCollectionsClient,
|
|
138
|
+
createConsumerCollectionsClient: () => createConsumerCollectionsClient,
|
|
139
|
+
createConsumerWithdrawalsClient: () => createConsumerWithdrawalsClient,
|
|
97
140
|
createFlurPartnerClient: () => createFlurPartnerClient,
|
|
98
141
|
createHmacFetch: () => createHmacFetch,
|
|
99
142
|
createMeOfflineClient: () => createMeOfflineClient,
|
|
100
143
|
createOfflineSettlementsClient: () => createOfflineSettlementsClient,
|
|
144
|
+
createPartnerCollectionsClient: () => createPartnerCollectionsClient,
|
|
145
|
+
createPartnerFundingClient: () => createPartnerFundingClient,
|
|
146
|
+
createPartnerProfileAdminClient: () => createPartnerProfileAdminClient,
|
|
101
147
|
createPassesClient: () => createPassesClient,
|
|
102
148
|
createReceiptsClient: () => createReceiptsClient,
|
|
103
149
|
decodeAuthorizationQR: () => decodeAuthorizationQR,
|
|
@@ -145,7 +191,7 @@ __export(index_exports, {
|
|
|
145
191
|
module.exports = __toCommonJS(index_exports);
|
|
146
192
|
|
|
147
193
|
// src/client.ts
|
|
148
|
-
var
|
|
194
|
+
var import_zod4 = require("zod");
|
|
149
195
|
|
|
150
196
|
// src/contracts.ts
|
|
151
197
|
var import_zod = require("zod");
|
|
@@ -298,6 +344,13 @@ var AccountActivityItemSchema = import_zod.z.object({
|
|
|
298
344
|
timestamp: IsoDateSchema
|
|
299
345
|
});
|
|
300
346
|
var AccountSummaryResponseSchema = import_zod.z.object({
|
|
347
|
+
/** Authenticated user's stable internal id. */
|
|
348
|
+
userId: UuidSchema,
|
|
349
|
+
/**
|
|
350
|
+
* 10-digit Nigeria Uniform Bank Account Number (NUBAN) allocated by the
|
|
351
|
+
* bank partner. `null` when the user has no partner-allocated account yet.
|
|
352
|
+
*/
|
|
353
|
+
nuban: import_zod.z.string().regex(/^[0-9]{10}$/).nullable(),
|
|
301
354
|
balance: import_zod.z.number().int(),
|
|
302
355
|
currency: CurrencySchema,
|
|
303
356
|
dailySendLimit: import_zod.z.number().int().nonnegative(),
|
|
@@ -533,6 +586,341 @@ function moneyMinorToNumber(amountMinor) {
|
|
|
533
586
|
return asNumber;
|
|
534
587
|
}
|
|
535
588
|
|
|
589
|
+
// src/collections/client.ts
|
|
590
|
+
var import_zod3 = require("zod");
|
|
591
|
+
var MERCHANT_PROFILE_STATUSES = [
|
|
592
|
+
"pending",
|
|
593
|
+
"active",
|
|
594
|
+
"suspended",
|
|
595
|
+
"closed"
|
|
596
|
+
];
|
|
597
|
+
var SETTLEMENT_SCHEDULES = ["manual", "daily", "t1"];
|
|
598
|
+
var COLLECTION_INTENT_STATUSES = [
|
|
599
|
+
"created",
|
|
600
|
+
"pending",
|
|
601
|
+
"paid",
|
|
602
|
+
"expired",
|
|
603
|
+
"cancelled",
|
|
604
|
+
"failed",
|
|
605
|
+
"reversed"
|
|
606
|
+
];
|
|
607
|
+
var COLLECTION_PAYMENT_STATUSES = [
|
|
608
|
+
"pending",
|
|
609
|
+
"paid",
|
|
610
|
+
"failed",
|
|
611
|
+
"reversed"
|
|
612
|
+
];
|
|
613
|
+
var MERCHANT_PAYOUT_STATUSES = [
|
|
614
|
+
"requested",
|
|
615
|
+
"processing",
|
|
616
|
+
"paid",
|
|
617
|
+
"failed",
|
|
618
|
+
"cancelled"
|
|
619
|
+
];
|
|
620
|
+
var MoneyKoboSchema = import_zod3.z.number().int().positive().max(Number.MAX_SAFE_INTEGER);
|
|
621
|
+
var MetadataSchema = import_zod3.z.record(
|
|
622
|
+
import_zod3.z.union([import_zod3.z.string(), import_zod3.z.number(), import_zod3.z.boolean(), import_zod3.z.null()])
|
|
623
|
+
);
|
|
624
|
+
var CurrencySchema2 = import_zod3.z.string().trim().length(3).transform((value) => value.toUpperCase());
|
|
625
|
+
var ReferenceSchema = import_zod3.z.string().trim().min(6).max(128).regex(/^[A-Za-z0-9._:-]+$/);
|
|
626
|
+
var MerchantProfileSchema = import_zod3.z.object({
|
|
627
|
+
accountId: import_zod3.z.string().uuid(),
|
|
628
|
+
legalName: import_zod3.z.string(),
|
|
629
|
+
tradingName: import_zod3.z.string(),
|
|
630
|
+
merchantCategoryCode: import_zod3.z.string().regex(/^\d{4}$/),
|
|
631
|
+
nqrMerchantId: import_zod3.z.string(),
|
|
632
|
+
settlementBankCode: import_zod3.z.string(),
|
|
633
|
+
settlementAccountNumber: import_zod3.z.string(),
|
|
634
|
+
settlementAccountName: import_zod3.z.string(),
|
|
635
|
+
settlementSchedule: import_zod3.z.enum(SETTLEMENT_SCHEDULES),
|
|
636
|
+
status: import_zod3.z.enum(MERCHANT_PROFILE_STATUSES),
|
|
637
|
+
offlineEnabled: import_zod3.z.boolean(),
|
|
638
|
+
perTxLimitKobo: MoneyKoboSchema,
|
|
639
|
+
dailyLimitKobo: MoneyKoboSchema,
|
|
640
|
+
metadata: MetadataSchema,
|
|
641
|
+
createdAtMs: import_zod3.z.number().int().nonnegative(),
|
|
642
|
+
updatedAtMs: import_zod3.z.number().int().nonnegative()
|
|
643
|
+
});
|
|
644
|
+
var UpsertMerchantProfileInputSchema = import_zod3.z.object({
|
|
645
|
+
legalName: import_zod3.z.string().trim().min(1).max(200),
|
|
646
|
+
tradingName: import_zod3.z.string().trim().min(1).max(25),
|
|
647
|
+
merchantCategoryCode: import_zod3.z.string().trim().regex(/^\d{4}$/),
|
|
648
|
+
nqrMerchantId: import_zod3.z.string().trim().min(3).max(64),
|
|
649
|
+
settlementBankCode: import_zod3.z.string().trim().min(2).max(16),
|
|
650
|
+
settlementAccountNumber: import_zod3.z.string().trim().min(5).max(32),
|
|
651
|
+
settlementAccountName: import_zod3.z.string().trim().min(1).max(200),
|
|
652
|
+
settlementSchedule: import_zod3.z.enum(SETTLEMENT_SCHEDULES).optional(),
|
|
653
|
+
status: import_zod3.z.enum(MERCHANT_PROFILE_STATUSES).optional(),
|
|
654
|
+
offlineEnabled: import_zod3.z.boolean().optional(),
|
|
655
|
+
perTxLimitKobo: MoneyKoboSchema.optional(),
|
|
656
|
+
dailyLimitKobo: MoneyKoboSchema.optional(),
|
|
657
|
+
metadata: MetadataSchema.optional()
|
|
658
|
+
});
|
|
659
|
+
var CollectionIntentSchema = import_zod3.z.object({
|
|
660
|
+
intentId: import_zod3.z.string().uuid(),
|
|
661
|
+
accountId: import_zod3.z.string().uuid(),
|
|
662
|
+
terminalId: import_zod3.z.string().uuid().nullable(),
|
|
663
|
+
reference: import_zod3.z.string(),
|
|
664
|
+
amountKobo: import_zod3.z.number().int().positive().nullable(),
|
|
665
|
+
currency: import_zod3.z.string().length(3),
|
|
666
|
+
status: import_zod3.z.enum(COLLECTION_INTENT_STATUSES),
|
|
667
|
+
description: import_zod3.z.string().nullable(),
|
|
668
|
+
nqrPayload: import_zod3.z.string(),
|
|
669
|
+
provider: import_zod3.z.string(),
|
|
670
|
+
providerReference: import_zod3.z.string().nullable(),
|
|
671
|
+
metadata: MetadataSchema,
|
|
672
|
+
expiresAtMs: import_zod3.z.number().int().nonnegative().nullable(),
|
|
673
|
+
paidAtMs: import_zod3.z.number().int().nonnegative().nullable(),
|
|
674
|
+
createdAtMs: import_zod3.z.number().int().nonnegative(),
|
|
675
|
+
updatedAtMs: import_zod3.z.number().int().nonnegative()
|
|
676
|
+
});
|
|
677
|
+
var CreateCollectionIntentInputSchema = import_zod3.z.object({
|
|
678
|
+
reference: ReferenceSchema.optional(),
|
|
679
|
+
amountKobo: MoneyKoboSchema.optional(),
|
|
680
|
+
currency: CurrencySchema2.optional(),
|
|
681
|
+
terminalId: import_zod3.z.string().uuid().optional(),
|
|
682
|
+
terminalLabel: import_zod3.z.string().trim().min(1).max(25).optional(),
|
|
683
|
+
merchantCity: import_zod3.z.string().trim().min(1).max(15).optional(),
|
|
684
|
+
description: import_zod3.z.string().trim().min(1).max(280).optional(),
|
|
685
|
+
expiresAtMs: import_zod3.z.number().int().positive().optional(),
|
|
686
|
+
provider: import_zod3.z.string().trim().min(1).max(40).optional(),
|
|
687
|
+
metadata: MetadataSchema.optional()
|
|
688
|
+
});
|
|
689
|
+
var PublicCollectionIntentSchema = import_zod3.z.object({
|
|
690
|
+
intentId: import_zod3.z.string().uuid(),
|
|
691
|
+
reference: import_zod3.z.string(),
|
|
692
|
+
amountKobo: import_zod3.z.number().int().positive().nullable(),
|
|
693
|
+
currency: import_zod3.z.string().length(3),
|
|
694
|
+
status: import_zod3.z.enum(COLLECTION_INTENT_STATUSES),
|
|
695
|
+
merchantAccountId: import_zod3.z.string().uuid(),
|
|
696
|
+
merchantName: import_zod3.z.string(),
|
|
697
|
+
merchantCategoryCode: import_zod3.z.string(),
|
|
698
|
+
description: import_zod3.z.string().nullable(),
|
|
699
|
+
expiresAtMs: import_zod3.z.number().int().nonnegative().nullable()
|
|
700
|
+
});
|
|
701
|
+
var PayCollectionInputSchema = import_zod3.z.object({
|
|
702
|
+
reference: ReferenceSchema,
|
|
703
|
+
amountKobo: MoneyKoboSchema.optional(),
|
|
704
|
+
currency: CurrencySchema2.optional(),
|
|
705
|
+
idempotencyKey: import_zod3.z.string().trim().min(8).max(160).optional()
|
|
706
|
+
});
|
|
707
|
+
var CollectionPaymentSchema = import_zod3.z.object({
|
|
708
|
+
paymentId: import_zod3.z.string().uuid(),
|
|
709
|
+
intentId: import_zod3.z.string().uuid(),
|
|
710
|
+
accountId: import_zod3.z.string().uuid(),
|
|
711
|
+
payerUserId: import_zod3.z.string().uuid().nullable(),
|
|
712
|
+
merchantOwnerUserId: import_zod3.z.string().uuid(),
|
|
713
|
+
amountKobo: MoneyKoboSchema,
|
|
714
|
+
currency: import_zod3.z.string().length(3),
|
|
715
|
+
status: import_zod3.z.enum(COLLECTION_PAYMENT_STATUSES),
|
|
716
|
+
provider: import_zod3.z.string(),
|
|
717
|
+
providerReference: import_zod3.z.string().nullable(),
|
|
718
|
+
idempotencyKey: import_zod3.z.string().nullable(),
|
|
719
|
+
ledgerRef: import_zod3.z.string(),
|
|
720
|
+
failureCode: import_zod3.z.string().nullable(),
|
|
721
|
+
failureMessage: import_zod3.z.string().nullable(),
|
|
722
|
+
paidAtMs: import_zod3.z.number().int().nonnegative().nullable(),
|
|
723
|
+
createdAtMs: import_zod3.z.number().int().nonnegative(),
|
|
724
|
+
updatedAtMs: import_zod3.z.number().int().nonnegative()
|
|
725
|
+
});
|
|
726
|
+
var CollectionPaymentResultSchema = import_zod3.z.object({
|
|
727
|
+
payment: CollectionPaymentSchema,
|
|
728
|
+
intent: CollectionIntentSchema,
|
|
729
|
+
receipt: import_zod3.z.unknown().optional(),
|
|
730
|
+
replayed: import_zod3.z.boolean()
|
|
731
|
+
});
|
|
732
|
+
var CollectionReportSummarySchema = import_zod3.z.object({
|
|
733
|
+
accountId: import_zod3.z.string().uuid(),
|
|
734
|
+
fromMs: import_zod3.z.number().int().nonnegative(),
|
|
735
|
+
toMs: import_zod3.z.number().int().nonnegative(),
|
|
736
|
+
currency: import_zod3.z.string().length(3),
|
|
737
|
+
paidCount: import_zod3.z.number().int().nonnegative(),
|
|
738
|
+
paidAmountKobo: import_zod3.z.number().int().nonnegative(),
|
|
739
|
+
pendingCount: import_zod3.z.number().int().nonnegative(),
|
|
740
|
+
failedCount: import_zod3.z.number().int().nonnegative(),
|
|
741
|
+
reversedCount: import_zod3.z.number().int().nonnegative(),
|
|
742
|
+
availableBalanceKobo: import_zod3.z.number().int().nonnegative()
|
|
743
|
+
});
|
|
744
|
+
var CollectionStatementSchema = import_zod3.z.object({
|
|
745
|
+
accountId: import_zod3.z.string().uuid(),
|
|
746
|
+
year: import_zod3.z.number().int(),
|
|
747
|
+
month: import_zod3.z.number().int().min(1).max(12),
|
|
748
|
+
currency: import_zod3.z.string().length(3),
|
|
749
|
+
totalPaidKobo: import_zod3.z.number().int().nonnegative(),
|
|
750
|
+
items: import_zod3.z.array(CollectionPaymentSchema)
|
|
751
|
+
});
|
|
752
|
+
var CreatePayoutInputSchema = import_zod3.z.object({
|
|
753
|
+
amountKobo: MoneyKoboSchema,
|
|
754
|
+
currency: CurrencySchema2.optional(),
|
|
755
|
+
idempotencyKey: import_zod3.z.string().trim().min(8).max(160)
|
|
756
|
+
});
|
|
757
|
+
var MerchantPayoutSchema = import_zod3.z.object({
|
|
758
|
+
payoutId: import_zod3.z.string().uuid(),
|
|
759
|
+
accountId: import_zod3.z.string().uuid(),
|
|
760
|
+
amountKobo: MoneyKoboSchema,
|
|
761
|
+
currency: import_zod3.z.string().length(3),
|
|
762
|
+
status: import_zod3.z.enum(MERCHANT_PAYOUT_STATUSES),
|
|
763
|
+
idempotencyKey: import_zod3.z.string().nullable(),
|
|
764
|
+
ledgerRef: import_zod3.z.string(),
|
|
765
|
+
providerReference: import_zod3.z.string().nullable(),
|
|
766
|
+
requestedByUserId: import_zod3.z.string().uuid().nullable(),
|
|
767
|
+
failureCode: import_zod3.z.string().nullable(),
|
|
768
|
+
failureMessage: import_zod3.z.string().nullable(),
|
|
769
|
+
createdAtMs: import_zod3.z.number().int().nonnegative(),
|
|
770
|
+
updatedAtMs: import_zod3.z.number().int().nonnegative()
|
|
771
|
+
});
|
|
772
|
+
var ProviderEventInputSchema = import_zod3.z.object({
|
|
773
|
+
provider: import_zod3.z.string().trim().min(1).max(80),
|
|
774
|
+
eventId: import_zod3.z.string().trim().min(1).max(160),
|
|
775
|
+
eventType: import_zod3.z.string().trim().min(1).max(120),
|
|
776
|
+
payload: import_zod3.z.record(import_zod3.z.unknown()).optional()
|
|
777
|
+
});
|
|
778
|
+
var ProviderEventRecordSchema = import_zod3.z.object({
|
|
779
|
+
id: import_zod3.z.string().uuid(),
|
|
780
|
+
provider: import_zod3.z.string(),
|
|
781
|
+
eventId: import_zod3.z.string(),
|
|
782
|
+
eventType: import_zod3.z.string(),
|
|
783
|
+
signatureVerified: import_zod3.z.boolean(),
|
|
784
|
+
receivedAtMs: import_zod3.z.number().int().nonnegative(),
|
|
785
|
+
processedAtMs: import_zod3.z.number().int().nonnegative().nullable()
|
|
786
|
+
});
|
|
787
|
+
function createCollectionsClient(opts) {
|
|
788
|
+
const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
|
|
789
|
+
if (!fetchImpl) {
|
|
790
|
+
throw new Error(
|
|
791
|
+
"createCollectionsClient: no fetch implementation available"
|
|
792
|
+
);
|
|
793
|
+
}
|
|
794
|
+
const baseUrl = opts.baseUrl.replace(/\/$/, "");
|
|
795
|
+
async function call(method, path, body, parser) {
|
|
796
|
+
const init2 = {
|
|
797
|
+
method,
|
|
798
|
+
headers: { accept: "application/json" }
|
|
799
|
+
};
|
|
800
|
+
if (body !== void 0) {
|
|
801
|
+
init2.body = JSON.stringify(body);
|
|
802
|
+
init2.headers = { ...init2.headers, "content-type": "application/json" };
|
|
803
|
+
}
|
|
804
|
+
const resp = await fetchImpl(`${baseUrl}${path}`, init2);
|
|
805
|
+
const text = await resp.text();
|
|
806
|
+
let raw;
|
|
807
|
+
if (text) {
|
|
808
|
+
try {
|
|
809
|
+
raw = JSON.parse(text);
|
|
810
|
+
} catch {
|
|
811
|
+
raw = text;
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
if (!resp.ok) {
|
|
815
|
+
const code = raw && typeof raw === "object" && "code" in raw && typeof raw.code === "string" ? raw.code : `http_${resp.status}`;
|
|
816
|
+
const message = raw && typeof raw === "object" && "message" in raw && typeof raw.message === "string" ? raw.message : `request failed with status ${resp.status}`;
|
|
817
|
+
throw new FlurApiError(resp.status, code, message, raw);
|
|
818
|
+
}
|
|
819
|
+
return parser(raw);
|
|
820
|
+
}
|
|
821
|
+
return {
|
|
822
|
+
upsertMerchantProfile: (accountId, input) => call(
|
|
823
|
+
"PUT",
|
|
824
|
+
`/v1/accounts/${encodeURIComponent(accountId)}/merchant-profile`,
|
|
825
|
+
UpsertMerchantProfileInputSchema.parse(input),
|
|
826
|
+
(raw) => MerchantProfileSchema.parse(raw)
|
|
827
|
+
),
|
|
828
|
+
getMerchantProfile: (accountId) => call(
|
|
829
|
+
"GET",
|
|
830
|
+
`/v1/accounts/${encodeURIComponent(accountId)}/merchant-profile`,
|
|
831
|
+
void 0,
|
|
832
|
+
(raw) => MerchantProfileSchema.parse(raw)
|
|
833
|
+
),
|
|
834
|
+
createIntent: (input) => call(
|
|
835
|
+
"POST",
|
|
836
|
+
"/v1/collections/intents",
|
|
837
|
+
CreateCollectionIntentInputSchema.parse(input),
|
|
838
|
+
(raw) => CollectionIntentSchema.parse(raw)
|
|
839
|
+
),
|
|
840
|
+
getIntent: (intentId) => call(
|
|
841
|
+
"GET",
|
|
842
|
+
`/v1/collections/intents/${encodeURIComponent(intentId)}`,
|
|
843
|
+
void 0,
|
|
844
|
+
(raw) => CollectionIntentSchema.parse(raw)
|
|
845
|
+
),
|
|
846
|
+
resolveIntent: (reference) => call(
|
|
847
|
+
"GET",
|
|
848
|
+
`/v1/collections/resolve/${encodeURIComponent(reference)}`,
|
|
849
|
+
void 0,
|
|
850
|
+
(raw) => PublicCollectionIntentSchema.parse(raw)
|
|
851
|
+
),
|
|
852
|
+
pay: (input) => call(
|
|
853
|
+
"POST",
|
|
854
|
+
"/v1/collections/pay",
|
|
855
|
+
PayCollectionInputSchema.parse(input),
|
|
856
|
+
(raw) => CollectionPaymentResultSchema.parse(raw)
|
|
857
|
+
),
|
|
858
|
+
reportSummary: (input) => {
|
|
859
|
+
const qs = new URLSearchParams({
|
|
860
|
+
fromMs: String(input.fromMs),
|
|
861
|
+
toMs: String(input.toMs)
|
|
862
|
+
});
|
|
863
|
+
if (input.currency) qs.set("currency", input.currency);
|
|
864
|
+
return call(
|
|
865
|
+
"GET",
|
|
866
|
+
`/v1/collections/reports/summary?${qs.toString()}`,
|
|
867
|
+
void 0,
|
|
868
|
+
(raw) => CollectionReportSummarySchema.parse(raw)
|
|
869
|
+
);
|
|
870
|
+
},
|
|
871
|
+
monthlyStatement: (input) => {
|
|
872
|
+
const qs = new URLSearchParams({
|
|
873
|
+
year: String(input.year),
|
|
874
|
+
month: String(input.month)
|
|
875
|
+
});
|
|
876
|
+
if (input.currency) qs.set("currency", input.currency);
|
|
877
|
+
return call(
|
|
878
|
+
"GET",
|
|
879
|
+
`/v1/collections/statements/monthly?${qs.toString()}`,
|
|
880
|
+
void 0,
|
|
881
|
+
(raw) => CollectionStatementSchema.parse(raw)
|
|
882
|
+
);
|
|
883
|
+
},
|
|
884
|
+
createPayout: (input) => call(
|
|
885
|
+
"POST",
|
|
886
|
+
"/v1/collections/payouts",
|
|
887
|
+
CreatePayoutInputSchema.parse(input),
|
|
888
|
+
(raw) => MerchantPayoutSchema.parse(raw)
|
|
889
|
+
),
|
|
890
|
+
getPayout: (payoutId) => call(
|
|
891
|
+
"GET",
|
|
892
|
+
`/v1/collections/payouts/${encodeURIComponent(payoutId)}`,
|
|
893
|
+
void 0,
|
|
894
|
+
(raw) => MerchantPayoutSchema.parse(raw)
|
|
895
|
+
),
|
|
896
|
+
recordProviderEvent: (input) => call(
|
|
897
|
+
"POST",
|
|
898
|
+
"/v1/collections/provider-events",
|
|
899
|
+
ProviderEventInputSchema.parse(input),
|
|
900
|
+
(raw) => ProviderEventRecordSchema.parse(raw)
|
|
901
|
+
)
|
|
902
|
+
};
|
|
903
|
+
}
|
|
904
|
+
function createPartnerCollectionsClient(opts) {
|
|
905
|
+
const client = createCollectionsClient(opts);
|
|
906
|
+
return {
|
|
907
|
+
createIntent: client.createIntent,
|
|
908
|
+
getIntent: client.getIntent,
|
|
909
|
+
reportSummary: client.reportSummary,
|
|
910
|
+
monthlyStatement: client.monthlyStatement,
|
|
911
|
+
createPayout: client.createPayout,
|
|
912
|
+
getPayout: client.getPayout,
|
|
913
|
+
recordProviderEvent: client.recordProviderEvent
|
|
914
|
+
};
|
|
915
|
+
}
|
|
916
|
+
function createConsumerCollectionsClient(opts) {
|
|
917
|
+
const client = createCollectionsClient(opts);
|
|
918
|
+
return {
|
|
919
|
+
resolveIntent: client.resolveIntent,
|
|
920
|
+
pay: client.pay
|
|
921
|
+
};
|
|
922
|
+
}
|
|
923
|
+
|
|
536
924
|
// src/client.ts
|
|
537
925
|
var FlurClient = class {
|
|
538
926
|
baseUrl;
|
|
@@ -781,6 +1169,36 @@ var FlurClient = class {
|
|
|
781
1169
|
}
|
|
782
1170
|
);
|
|
783
1171
|
}
|
|
1172
|
+
async resolveCollection(reference, options) {
|
|
1173
|
+
return this.requestJson(
|
|
1174
|
+
`/v1/collections/resolve/${encodeURIComponent(reference)}`,
|
|
1175
|
+
{
|
|
1176
|
+
method: "GET",
|
|
1177
|
+
headers: {
|
|
1178
|
+
authorization: `Bearer ${options.accessToken}`
|
|
1179
|
+
}
|
|
1180
|
+
},
|
|
1181
|
+
void 0,
|
|
1182
|
+
PublicCollectionIntentSchema
|
|
1183
|
+
);
|
|
1184
|
+
}
|
|
1185
|
+
async payCollection(input, options) {
|
|
1186
|
+
const idempotencyKey = input.idempotencyKey ?? options.idempotencyKey ?? getSecureRandomUuid();
|
|
1187
|
+
return this.requestJson(
|
|
1188
|
+
"/v1/collections/pay",
|
|
1189
|
+
{
|
|
1190
|
+
method: "POST",
|
|
1191
|
+
headers: {
|
|
1192
|
+
"content-type": "application/json",
|
|
1193
|
+
authorization: `Bearer ${options.accessToken}`,
|
|
1194
|
+
"x-idempotency-key": idempotencyKey
|
|
1195
|
+
}
|
|
1196
|
+
},
|
|
1197
|
+
PayCollectionInputSchema,
|
|
1198
|
+
CollectionPaymentResultSchema,
|
|
1199
|
+
{ ...input, idempotencyKey }
|
|
1200
|
+
);
|
|
1201
|
+
}
|
|
784
1202
|
async accountSummary(options) {
|
|
785
1203
|
return this.requestJson(
|
|
786
1204
|
"/api/v1/account/summary",
|
|
@@ -879,7 +1297,7 @@ var FlurClient = class {
|
|
|
879
1297
|
try {
|
|
880
1298
|
body = requestSchema ? JSON.stringify(requestSchema.parse(input)) : init2.body;
|
|
881
1299
|
} catch (err) {
|
|
882
|
-
if (err instanceof
|
|
1300
|
+
if (err instanceof import_zod4.z.ZodError) {
|
|
883
1301
|
throw new FlurError("Invalid request payload", "INVALID_REQUEST", {
|
|
884
1302
|
details: err.flatten()
|
|
885
1303
|
});
|
|
@@ -907,7 +1325,7 @@ var FlurClient = class {
|
|
|
907
1325
|
try {
|
|
908
1326
|
return responseSchema.parse(payload);
|
|
909
1327
|
} catch (err) {
|
|
910
|
-
if (err instanceof
|
|
1328
|
+
if (err instanceof import_zod4.z.ZodError) {
|
|
911
1329
|
throw new FlurError(
|
|
912
1330
|
"SDK contract validation failed",
|
|
913
1331
|
"INVALID_REQUEST",
|
|
@@ -1365,24 +1783,24 @@ function verifyCanonical(value, signature, publicKey) {
|
|
|
1365
1783
|
}
|
|
1366
1784
|
|
|
1367
1785
|
// src/offline/oac.ts
|
|
1368
|
-
var
|
|
1786
|
+
var import_zod5 = require("zod");
|
|
1369
1787
|
var OAC_DEFAULT_PER_TX_KOBO = 5e5;
|
|
1370
1788
|
var OAC_DEFAULT_CUMULATIVE_KOBO = 2e6;
|
|
1371
1789
|
var OAC_DEFAULT_VALIDITY_MS = 24 * 60 * 60 * 1e3;
|
|
1372
|
-
var HexString = (length) =>
|
|
1790
|
+
var HexString = (length) => import_zod5.z.string().regex(
|
|
1373
1791
|
new RegExp(`^[0-9a-fA-F]{${length * 2}}$`),
|
|
1374
1792
|
`expected ${length}-byte hex string`
|
|
1375
1793
|
);
|
|
1376
|
-
var OACSchema =
|
|
1377
|
-
userId:
|
|
1378
|
-
deviceId:
|
|
1794
|
+
var OACSchema = import_zod5.z.object({
|
|
1795
|
+
userId: import_zod5.z.string().min(1),
|
|
1796
|
+
deviceId: import_zod5.z.string().min(1),
|
|
1379
1797
|
devicePublicKey: HexString(32),
|
|
1380
|
-
perTxCapKobo:
|
|
1381
|
-
cumulativeCapKobo:
|
|
1382
|
-
validFromMs:
|
|
1383
|
-
validUntilMs:
|
|
1384
|
-
counterSeed:
|
|
1385
|
-
nonce:
|
|
1798
|
+
perTxCapKobo: import_zod5.z.number().int().nonnegative(),
|
|
1799
|
+
cumulativeCapKobo: import_zod5.z.number().int().nonnegative(),
|
|
1800
|
+
validFromMs: import_zod5.z.number().int().nonnegative(),
|
|
1801
|
+
validUntilMs: import_zod5.z.number().int().positive(),
|
|
1802
|
+
counterSeed: import_zod5.z.number().int().nonnegative(),
|
|
1803
|
+
nonce: import_zod5.z.string().min(1),
|
|
1386
1804
|
issuerSig: HexString(64)
|
|
1387
1805
|
}).refine((v) => v.validUntilMs > v.validFromMs, {
|
|
1388
1806
|
message: "validUntilMs must be greater than validFromMs"
|
|
@@ -1489,19 +1907,19 @@ function decodeBase45(s) {
|
|
|
1489
1907
|
}
|
|
1490
1908
|
|
|
1491
1909
|
// src/offline/messages.ts
|
|
1492
|
-
var
|
|
1493
|
-
var HexSig =
|
|
1494
|
-
var OfflinePaymentRequestSchema =
|
|
1495
|
-
reference:
|
|
1496
|
-
amountKobo:
|
|
1910
|
+
var import_zod6 = require("zod");
|
|
1911
|
+
var HexSig = import_zod6.z.string().regex(/^[0-9a-fA-F]{128}$/, "expected 64-byte hex signature");
|
|
1912
|
+
var OfflinePaymentRequestSchema = import_zod6.z.object({
|
|
1913
|
+
reference: import_zod6.z.string().min(1),
|
|
1914
|
+
amountKobo: import_zod6.z.number().int().positive(),
|
|
1497
1915
|
merchantOAC: OACSchema,
|
|
1498
|
-
expiresAtMs:
|
|
1916
|
+
expiresAtMs: import_zod6.z.number().int().positive(),
|
|
1499
1917
|
merchantSig: HexSig
|
|
1500
1918
|
});
|
|
1501
|
-
var OfflinePaymentAuthorizationSchema =
|
|
1919
|
+
var OfflinePaymentAuthorizationSchema = import_zod6.z.object({
|
|
1502
1920
|
request: OfflinePaymentRequestSchema,
|
|
1503
1921
|
payerOAC: OACSchema,
|
|
1504
|
-
payerCounter:
|
|
1922
|
+
payerCounter: import_zod6.z.number().int().positive(),
|
|
1505
1923
|
payerSig: HexSig
|
|
1506
1924
|
});
|
|
1507
1925
|
function buildPaymentRequest(input) {
|
|
@@ -1610,56 +2028,56 @@ function decodeAuthorizationQR(s) {
|
|
|
1610
2028
|
}
|
|
1611
2029
|
|
|
1612
2030
|
// src/offline/settlements.ts
|
|
1613
|
-
var
|
|
2031
|
+
var import_zod7 = require("zod");
|
|
1614
2032
|
var import_sha256 = require("@noble/hashes/sha256");
|
|
1615
2033
|
var import_utils = require("@noble/hashes/utils");
|
|
1616
|
-
var OfflineTokenSchema =
|
|
1617
|
-
tokenId:
|
|
1618
|
-
tokenSerial:
|
|
1619
|
-
issuerAccountId:
|
|
1620
|
-
payerUserId:
|
|
1621
|
-
maxAmountKobo:
|
|
1622
|
-
currency:
|
|
1623
|
-
issuedAtMs:
|
|
1624
|
-
expiresAtMs:
|
|
1625
|
-
issuerSig:
|
|
1626
|
-
});
|
|
1627
|
-
var PaymentClaimSchema =
|
|
1628
|
-
encounterId:
|
|
1629
|
-
tokenSerial:
|
|
1630
|
-
payerUserId:
|
|
1631
|
-
payeeUserId:
|
|
1632
|
-
payerNonce:
|
|
1633
|
-
payeeNonce:
|
|
1634
|
-
amountKobo:
|
|
1635
|
-
currency:
|
|
1636
|
-
occurredAtMs:
|
|
1637
|
-
completedAtMs:
|
|
1638
|
-
contextId:
|
|
1639
|
-
payerPubkey:
|
|
1640
|
-
payerSignature:
|
|
1641
|
-
payeePubkey:
|
|
1642
|
-
payeeSignature:
|
|
1643
|
-
});
|
|
1644
|
-
var SettlementSchema =
|
|
1645
|
-
settlementId:
|
|
1646
|
-
settlementKey:
|
|
1647
|
-
encounterId:
|
|
1648
|
-
issuerAccountId:
|
|
1649
|
-
tokenSerial:
|
|
1650
|
-
payerUserId:
|
|
1651
|
-
payeeUserId:
|
|
1652
|
-
amountKobo:
|
|
1653
|
-
currency:
|
|
1654
|
-
receiptId:
|
|
1655
|
-
status:
|
|
1656
|
-
issuerSig:
|
|
1657
|
-
createdAtMs:
|
|
1658
|
-
});
|
|
1659
|
-
var SettleResponseSchema =
|
|
2034
|
+
var OfflineTokenSchema = import_zod7.z.object({
|
|
2035
|
+
tokenId: import_zod7.z.string().uuid(),
|
|
2036
|
+
tokenSerial: import_zod7.z.string(),
|
|
2037
|
+
issuerAccountId: import_zod7.z.string().uuid(),
|
|
2038
|
+
payerUserId: import_zod7.z.string().uuid(),
|
|
2039
|
+
maxAmountKobo: import_zod7.z.number().int().positive(),
|
|
2040
|
+
currency: import_zod7.z.string().length(3),
|
|
2041
|
+
issuedAtMs: import_zod7.z.number().int().nonnegative(),
|
|
2042
|
+
expiresAtMs: import_zod7.z.number().int().nonnegative(),
|
|
2043
|
+
issuerSig: import_zod7.z.string()
|
|
2044
|
+
});
|
|
2045
|
+
var PaymentClaimSchema = import_zod7.z.object({
|
|
2046
|
+
encounterId: import_zod7.z.string().regex(/^[0-9a-f]{64}$/i).optional(),
|
|
2047
|
+
tokenSerial: import_zod7.z.string(),
|
|
2048
|
+
payerUserId: import_zod7.z.string().uuid(),
|
|
2049
|
+
payeeUserId: import_zod7.z.string().uuid(),
|
|
2050
|
+
payerNonce: import_zod7.z.string(),
|
|
2051
|
+
payeeNonce: import_zod7.z.string(),
|
|
2052
|
+
amountKobo: import_zod7.z.number().int().positive(),
|
|
2053
|
+
currency: import_zod7.z.string().length(3).default("NGN"),
|
|
2054
|
+
occurredAtMs: import_zod7.z.number().int().nonnegative(),
|
|
2055
|
+
completedAtMs: import_zod7.z.number().int().nonnegative().optional(),
|
|
2056
|
+
contextId: import_zod7.z.string().optional(),
|
|
2057
|
+
payerPubkey: import_zod7.z.string().regex(/^[0-9a-f]{64}$/i),
|
|
2058
|
+
payerSignature: import_zod7.z.string().regex(/^[0-9a-f]+$/i),
|
|
2059
|
+
payeePubkey: import_zod7.z.string().regex(/^[0-9a-f]{64}$/i).optional(),
|
|
2060
|
+
payeeSignature: import_zod7.z.string().regex(/^[0-9a-f]+$/i).optional()
|
|
2061
|
+
});
|
|
2062
|
+
var SettlementSchema = import_zod7.z.object({
|
|
2063
|
+
settlementId: import_zod7.z.string().uuid(),
|
|
2064
|
+
settlementKey: import_zod7.z.string().regex(/^[0-9a-f]{64}$/i),
|
|
2065
|
+
encounterId: import_zod7.z.string().regex(/^[0-9a-f]{64}$/i),
|
|
2066
|
+
issuerAccountId: import_zod7.z.string().uuid(),
|
|
2067
|
+
tokenSerial: import_zod7.z.string(),
|
|
2068
|
+
payerUserId: import_zod7.z.string().uuid(),
|
|
2069
|
+
payeeUserId: import_zod7.z.string().uuid(),
|
|
2070
|
+
amountKobo: import_zod7.z.number().int().nonnegative(),
|
|
2071
|
+
currency: import_zod7.z.string().length(3),
|
|
2072
|
+
receiptId: import_zod7.z.string().nullable(),
|
|
2073
|
+
status: import_zod7.z.enum(["SETTLED", "REVIEW", "REJECTED"]),
|
|
2074
|
+
issuerSig: import_zod7.z.string(),
|
|
2075
|
+
createdAtMs: import_zod7.z.number().int().nonnegative()
|
|
2076
|
+
});
|
|
2077
|
+
var SettleResponseSchema = import_zod7.z.object({
|
|
1660
2078
|
settlement: SettlementSchema,
|
|
1661
|
-
encounterId:
|
|
1662
|
-
replayed:
|
|
2079
|
+
encounterId: import_zod7.z.string().regex(/^[0-9a-f]{64}$/i),
|
|
2080
|
+
replayed: import_zod7.z.boolean()
|
|
1663
2081
|
});
|
|
1664
2082
|
var ENCOUNTER_DOMAIN = "offline:v1:encounter";
|
|
1665
2083
|
async function sha256Hex(input) {
|
|
@@ -1832,133 +2250,351 @@ function createHmacFetch(opts) {
|
|
|
1832
2250
|
});
|
|
1833
2251
|
}
|
|
1834
2252
|
|
|
1835
|
-
// src/
|
|
1836
|
-
var
|
|
1837
|
-
var
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
"
|
|
1842
|
-
"
|
|
1843
|
-
"
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
"
|
|
1847
|
-
"
|
|
1848
|
-
"
|
|
1849
|
-
"
|
|
1850
|
-
"
|
|
2253
|
+
// src/partner/client.ts
|
|
2254
|
+
var import_zod8 = require("zod");
|
|
2255
|
+
var import_sha2563 = require("@noble/hashes/sha256");
|
|
2256
|
+
var import_hmac4 = require("@noble/hashes/hmac");
|
|
2257
|
+
var import_utils2 = require("@noble/hashes/utils");
|
|
2258
|
+
var PARTNER_SCOPES = [
|
|
2259
|
+
"passes:write",
|
|
2260
|
+
"passes:read",
|
|
2261
|
+
"passes:redeem",
|
|
2262
|
+
"receipts:write",
|
|
2263
|
+
"receipts:read",
|
|
2264
|
+
"offline:issue",
|
|
2265
|
+
"offline:settle",
|
|
2266
|
+
"offline:read",
|
|
2267
|
+
"collections:write",
|
|
2268
|
+
"collections:read",
|
|
2269
|
+
"collections:pay",
|
|
2270
|
+
"collections:webhook",
|
|
2271
|
+
"reports:read",
|
|
2272
|
+
"payouts:write",
|
|
2273
|
+
"payouts:read",
|
|
2274
|
+
"partner:funding:write",
|
|
2275
|
+
"partner:payout:write",
|
|
2276
|
+
"partner:reconciliation:read"
|
|
1851
2277
|
];
|
|
1852
|
-
var
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
)
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
)
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
/** Optional client/template grouping id (server may omit). */
|
|
1862
|
-
templateId: import_zod7.z.string().min(1).optional(),
|
|
1863
|
-
/** Optional human-facing holder identity (server may omit). The cryptographic binding
|
|
1864
|
-
* is `holderDevicePubkey` below. */
|
|
1865
|
-
holderUserId: import_zod7.z.string().min(1).optional(),
|
|
1866
|
-
kind: import_zod7.z.enum(PASS_KINDS),
|
|
1867
|
-
issuerId: import_zod7.z.string().min(1),
|
|
1868
|
-
issuedAtMs: import_zod7.z.number().int().nonnegative(),
|
|
1869
|
-
validFromMs: import_zod7.z.number().int().nonnegative(),
|
|
1870
|
-
validUntilMs: import_zod7.z.number().int().positive(),
|
|
1871
|
-
state: import_zod7.z.enum(PASS_STATES),
|
|
1872
|
-
metadata: PassMetadataSchema,
|
|
1873
|
-
nonce: import_zod7.z.string().min(1),
|
|
1874
|
-
/** Device id this pass is bound to (FK to backend `device_keys`). */
|
|
1875
|
-
holderDeviceId: import_zod7.z.string().min(1),
|
|
1876
|
-
/** 32-byte hex Ed25519 public key of the bound device. The redemption signature
|
|
1877
|
-
* is verified against this key — it is the security-critical binding. */
|
|
1878
|
-
holderDevicePubkey: HexString2(32),
|
|
1879
|
-
/** Optional fixed amount for monetary passes (vouchers, gift cards) in kobo. */
|
|
1880
|
-
amountKobo: import_zod7.z.number().int().nonnegative().optional(),
|
|
1881
|
-
/** ISO-4217-ish currency code; required on the wire. SDK builders default to NGN. */
|
|
1882
|
-
currency: import_zod7.z.string().min(3).max(8),
|
|
1883
|
-
/** Monotonic redemption counter floor. Redemption.counter MUST be > counterSeed. */
|
|
1884
|
-
counterSeed: import_zod7.z.number().int().nonnegative(),
|
|
1885
|
-
/** Optional cumulative spend cap in kobo across all redemptions of this pass. */
|
|
1886
|
-
cumulativeCapKobo: import_zod7.z.number().int().nonnegative().optional(),
|
|
1887
|
-
issuerSig: HexString2(64)
|
|
1888
|
-
}).refine((v) => v.validUntilMs > v.validFromMs, {
|
|
1889
|
-
message: "validUntilMs must be greater than validFromMs"
|
|
2278
|
+
var ApiCredentialPublicSchema = import_zod8.z.object({
|
|
2279
|
+
id: import_zod8.z.string().uuid(),
|
|
2280
|
+
accountId: import_zod8.z.string().uuid(),
|
|
2281
|
+
keyId: import_zod8.z.string(),
|
|
2282
|
+
scopes: import_zod8.z.array(import_zod8.z.enum(PARTNER_SCOPES)),
|
|
2283
|
+
label: import_zod8.z.string().nullable(),
|
|
2284
|
+
createdAtMs: import_zod8.z.number().int().nonnegative(),
|
|
2285
|
+
lastUsedAtMs: import_zod8.z.number().int().nonnegative().nullable(),
|
|
2286
|
+
revokedAtMs: import_zod8.z.number().int().nonnegative().nullable()
|
|
1890
2287
|
});
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
issuerId: input.issuerId,
|
|
1899
|
-
issuedAtMs: input.issuedAtMs,
|
|
1900
|
-
validFromMs: input.validFromMs,
|
|
1901
|
-
validUntilMs: input.validUntilMs,
|
|
1902
|
-
state: input.state,
|
|
1903
|
-
metadata: input.metadata,
|
|
1904
|
-
nonce: input.nonce,
|
|
1905
|
-
holderDeviceId: input.holderDeviceId,
|
|
1906
|
-
holderDevicePubkey: input.holderDevicePubkey,
|
|
1907
|
-
currency: input.currency ?? "NGN",
|
|
1908
|
-
counterSeed: input.counterSeed
|
|
1909
|
-
};
|
|
1910
|
-
if (typeof input.templateId === "string") out.templateId = input.templateId;
|
|
1911
|
-
if (typeof input.holderUserId === "string")
|
|
1912
|
-
out.holderUserId = input.holderUserId;
|
|
1913
|
-
if (typeof input.amountKobo === "number") out.amountKobo = input.amountKobo;
|
|
1914
|
-
if (typeof input.cumulativeCapKobo === "number") {
|
|
1915
|
-
out.cumulativeCapKobo = input.cumulativeCapKobo;
|
|
1916
|
-
}
|
|
1917
|
-
return out;
|
|
2288
|
+
var MintedApiCredentialSchema = ApiCredentialPublicSchema.extend({
|
|
2289
|
+
secret: import_zod8.z.string().min(1)
|
|
2290
|
+
});
|
|
2291
|
+
var enc = new TextEncoder();
|
|
2292
|
+
async function sha256Hex2(input) {
|
|
2293
|
+
const data = typeof input === "string" ? enc.encode(input) : input;
|
|
2294
|
+
return (0, import_utils2.bytesToHex)((0, import_sha2563.sha256)(data));
|
|
1918
2295
|
}
|
|
1919
|
-
function
|
|
1920
|
-
|
|
1921
|
-
sign(canonicalJSONBytes(unsigned), issuerPrivateKey)
|
|
1922
|
-
);
|
|
1923
|
-
return { ...unsigned, issuerSig };
|
|
2296
|
+
async function hmacSha256Hex(keyHex, message) {
|
|
2297
|
+
return (0, import_utils2.bytesToHex)((0, import_hmac4.hmac)(import_sha2563.sha256, enc.encode(keyHex), enc.encode(message)));
|
|
1924
2298
|
}
|
|
1925
|
-
function
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
return verify(
|
|
1930
|
-
canonicalJSONBytes(unsigned),
|
|
1931
|
-
hexToBytes(issuerSig),
|
|
1932
|
-
issuerPublicKey
|
|
1933
|
-
);
|
|
1934
|
-
} catch {
|
|
1935
|
-
return false;
|
|
1936
|
-
}
|
|
2299
|
+
function defaultNonce2() {
|
|
2300
|
+
const c = globalThis.crypto;
|
|
2301
|
+
if (c?.randomUUID) return c.randomUUID();
|
|
2302
|
+
return `${Date.now().toString(16)}-${Math.random().toString(16).slice(2)}`;
|
|
1937
2303
|
}
|
|
1938
|
-
function
|
|
1939
|
-
return
|
|
2304
|
+
function canonical(params) {
|
|
2305
|
+
return [
|
|
2306
|
+
params.method.toUpperCase(),
|
|
2307
|
+
params.path,
|
|
2308
|
+
params.ts,
|
|
2309
|
+
params.nonce,
|
|
2310
|
+
params.bodyHash
|
|
2311
|
+
].join("\n");
|
|
1940
2312
|
}
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
}
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
2313
|
+
async function signPartnerRequest(params) {
|
|
2314
|
+
const ts = String(Math.floor((params.nowMs ?? Date.now()) / 1e3));
|
|
2315
|
+
const nonce = params.nonce ?? defaultNonce2();
|
|
2316
|
+
const bodyData = typeof params.body === "string" ? enc.encode(params.body) : params.body ?? new Uint8Array();
|
|
2317
|
+
const bodyHash = await sha256Hex2(bodyData);
|
|
2318
|
+
const message = canonical({
|
|
2319
|
+
method: params.method,
|
|
2320
|
+
path: params.path,
|
|
2321
|
+
ts,
|
|
2322
|
+
nonce,
|
|
2323
|
+
bodyHash
|
|
2324
|
+
});
|
|
2325
|
+
const signingKey = await sha256Hex2(params.secret);
|
|
2326
|
+
const sig = await hmacSha256Hex(signingKey, message);
|
|
2327
|
+
return {
|
|
2328
|
+
authorization: `Flur-Hmac key=${params.keyId}, ts=${ts}, nonce=${nonce}, sig=${sig}`,
|
|
2329
|
+
ts,
|
|
2330
|
+
nonce,
|
|
2331
|
+
bodyHash
|
|
2332
|
+
};
|
|
2333
|
+
}
|
|
2334
|
+
function createFlurPartnerClient(opts) {
|
|
2335
|
+
const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
|
|
2336
|
+
if (!fetchImpl) {
|
|
2337
|
+
throw new Error(
|
|
2338
|
+
"createFlurPartnerClient: no fetch implementation available"
|
|
2339
|
+
);
|
|
2340
|
+
}
|
|
2341
|
+
const baseUrl = opts.baseUrl.replace(/\/$/, "");
|
|
2342
|
+
const scopeHeader = normalizeScopeHeader(opts.scope);
|
|
2343
|
+
async function makeSignedInit(method, path, body) {
|
|
2344
|
+
const sig = await signPartnerRequest({
|
|
2345
|
+
keyId: opts.keyId,
|
|
2346
|
+
secret: opts.secret,
|
|
2347
|
+
method,
|
|
2348
|
+
path,
|
|
2349
|
+
body: body ?? "",
|
|
2350
|
+
nowMs: opts.nowMs?.(),
|
|
2351
|
+
nonce: opts.nonce?.()
|
|
2352
|
+
});
|
|
2353
|
+
const headers = {
|
|
2354
|
+
authorization: sig.authorization,
|
|
2355
|
+
accept: "application/json"
|
|
2356
|
+
};
|
|
2357
|
+
if (scopeHeader) headers["x-flur-scope"] = scopeHeader;
|
|
2358
|
+
if (body !== void 0) headers["content-type"] = "application/json";
|
|
2359
|
+
const init2 = { method, headers };
|
|
2360
|
+
if (body !== void 0) init2.body = body;
|
|
2361
|
+
return init2;
|
|
2362
|
+
}
|
|
2363
|
+
async function request(opts2) {
|
|
2364
|
+
const bodyStr = opts2.body === void 0 ? void 0 : JSON.stringify(opts2.body);
|
|
2365
|
+
const init2 = await makeSignedInit(opts2.method, opts2.path, bodyStr);
|
|
2366
|
+
const resp = await fetchImpl(`${baseUrl}${opts2.path}`, init2);
|
|
2367
|
+
const text = await resp.text();
|
|
2368
|
+
let raw;
|
|
2369
|
+
if (text) {
|
|
2370
|
+
try {
|
|
2371
|
+
raw = JSON.parse(text);
|
|
2372
|
+
} catch {
|
|
2373
|
+
}
|
|
2374
|
+
}
|
|
2375
|
+
if (!resp.ok) {
|
|
2376
|
+
const code = raw && typeof raw === "object" && "code" in raw && typeof raw.code === "string" ? raw.code : `http_${resp.status}`;
|
|
2377
|
+
const message = raw && typeof raw === "object" && "message" in raw && typeof raw.message === "string" ? raw.message : `request failed with status ${resp.status}`;
|
|
2378
|
+
throw new FlurApiError(resp.status, code, message, raw);
|
|
2379
|
+
}
|
|
2380
|
+
return raw;
|
|
2381
|
+
}
|
|
2382
|
+
const fetchLike = async (input, init2) => {
|
|
2383
|
+
const url = typeof input === "string" ? input : input.toString();
|
|
2384
|
+
const u = new URL(url, baseUrl);
|
|
2385
|
+
const path = `${u.pathname}${u.search}`;
|
|
2386
|
+
const method = (init2?.method ?? "GET").toUpperCase();
|
|
2387
|
+
let bodyStr;
|
|
2388
|
+
if (init2?.body) {
|
|
2389
|
+
bodyStr = typeof init2.body === "string" ? init2.body : init2.body.toString();
|
|
2390
|
+
}
|
|
2391
|
+
const signed = await makeSignedInit(method, path, bodyStr);
|
|
2392
|
+
return fetchImpl(`${baseUrl}${path}`, {
|
|
2393
|
+
...init2,
|
|
2394
|
+
...signed,
|
|
2395
|
+
headers: {
|
|
2396
|
+
...init2?.headers,
|
|
2397
|
+
...signed.headers
|
|
2398
|
+
}
|
|
2399
|
+
});
|
|
2400
|
+
};
|
|
2401
|
+
return { request, fetch: fetchLike };
|
|
2402
|
+
}
|
|
2403
|
+
function normalizeScopeHeader(scope) {
|
|
2404
|
+
if (!scope || scope.length === 0) return void 0;
|
|
2405
|
+
const unique = Array.from(new Set(scope));
|
|
2406
|
+
for (const item of unique) {
|
|
2407
|
+
if (!PARTNER_SCOPES.includes(item)) {
|
|
2408
|
+
throw new Error(`unsupported partner scope: ${item}`);
|
|
2409
|
+
}
|
|
2410
|
+
}
|
|
2411
|
+
return unique.join(" ");
|
|
2412
|
+
}
|
|
2413
|
+
function createApiCredentialsAdminClient(opts) {
|
|
2414
|
+
const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
|
|
2415
|
+
if (!fetchImpl) {
|
|
2416
|
+
throw new Error(
|
|
2417
|
+
"createApiCredentialsAdminClient: no fetch implementation available"
|
|
2418
|
+
);
|
|
2419
|
+
}
|
|
2420
|
+
const baseUrl = opts.baseUrl.replace(/\/$/, "");
|
|
2421
|
+
async function call(method, path, body, parser) {
|
|
2422
|
+
const init2 = {
|
|
2423
|
+
method,
|
|
2424
|
+
headers: {
|
|
2425
|
+
"content-type": "application/json",
|
|
2426
|
+
accept: "application/json"
|
|
2427
|
+
}
|
|
2428
|
+
};
|
|
2429
|
+
if (body !== void 0) init2.body = JSON.stringify(body);
|
|
2430
|
+
const resp = await fetchImpl(`${baseUrl}${path}`, init2);
|
|
2431
|
+
const text = await resp.text();
|
|
2432
|
+
let raw;
|
|
2433
|
+
if (text) {
|
|
2434
|
+
try {
|
|
2435
|
+
raw = JSON.parse(text);
|
|
2436
|
+
} catch {
|
|
2437
|
+
}
|
|
2438
|
+
}
|
|
2439
|
+
if (!resp.ok) {
|
|
2440
|
+
const code = raw && typeof raw === "object" && "code" in raw && typeof raw.code === "string" ? raw.code : `http_${resp.status}`;
|
|
2441
|
+
const message = raw && typeof raw === "object" && "message" in raw && typeof raw.message === "string" ? raw.message : `request failed with status ${resp.status}`;
|
|
2442
|
+
throw new FlurApiError(resp.status, code, message, raw);
|
|
2443
|
+
}
|
|
2444
|
+
return parser(raw);
|
|
2445
|
+
}
|
|
2446
|
+
const listSchema = import_zod8.z.object({
|
|
2447
|
+
items: import_zod8.z.array(ApiCredentialPublicSchema)
|
|
2448
|
+
});
|
|
2449
|
+
return {
|
|
2450
|
+
list: (accountId) => call(
|
|
2451
|
+
"GET",
|
|
2452
|
+
`/v1/accounts/${accountId}/api-credentials`,
|
|
2453
|
+
void 0,
|
|
2454
|
+
(raw) => listSchema.parse(raw)
|
|
2455
|
+
),
|
|
2456
|
+
mint: (accountId, input) => call(
|
|
2457
|
+
"POST",
|
|
2458
|
+
`/v1/accounts/${accountId}/api-credentials`,
|
|
2459
|
+
input,
|
|
2460
|
+
(raw) => MintedApiCredentialSchema.parse(raw)
|
|
2461
|
+
),
|
|
2462
|
+
revoke: (accountId, credentialId) => call(
|
|
2463
|
+
"DELETE",
|
|
2464
|
+
`/v1/accounts/${accountId}/api-credentials/${credentialId}`,
|
|
2465
|
+
void 0,
|
|
2466
|
+
(raw) => ApiCredentialPublicSchema.parse(raw)
|
|
2467
|
+
)
|
|
2468
|
+
};
|
|
2469
|
+
}
|
|
2470
|
+
|
|
2471
|
+
// src/passes/pass.ts
|
|
2472
|
+
var import_zod9 = require("zod");
|
|
2473
|
+
var PASS_KINDS = [
|
|
2474
|
+
"ride-ticket",
|
|
2475
|
+
"transit-pass",
|
|
2476
|
+
"event-ticket",
|
|
2477
|
+
"voucher",
|
|
2478
|
+
"loyalty",
|
|
2479
|
+
"receipt-link"
|
|
2480
|
+
];
|
|
2481
|
+
var PASS_STATES = [
|
|
2482
|
+
"issued",
|
|
2483
|
+
"active",
|
|
2484
|
+
"redeemed",
|
|
2485
|
+
"expired",
|
|
2486
|
+
"revoked"
|
|
2487
|
+
];
|
|
2488
|
+
var HexString2 = (length) => import_zod9.z.string().regex(
|
|
2489
|
+
new RegExp(`^[0-9a-fA-F]{${length * 2}}$`),
|
|
2490
|
+
`expected ${length}-byte hex string`
|
|
2491
|
+
);
|
|
2492
|
+
var PassMetadataSchema = import_zod9.z.record(
|
|
2493
|
+
import_zod9.z.union([import_zod9.z.string(), import_zod9.z.number(), import_zod9.z.boolean(), import_zod9.z.null()])
|
|
2494
|
+
);
|
|
2495
|
+
var PassSchema = import_zod9.z.object({
|
|
2496
|
+
passId: import_zod9.z.string().min(1),
|
|
2497
|
+
/** Optional client/template grouping id (server may omit). */
|
|
2498
|
+
templateId: import_zod9.z.string().min(1).optional(),
|
|
2499
|
+
/** Optional human-facing holder identity (server may omit). The cryptographic binding
|
|
2500
|
+
* is `holderDevicePubkey` below. */
|
|
2501
|
+
holderUserId: import_zod9.z.string().min(1).optional(),
|
|
2502
|
+
kind: import_zod9.z.enum(PASS_KINDS),
|
|
2503
|
+
issuerId: import_zod9.z.string().min(1),
|
|
2504
|
+
issuedAtMs: import_zod9.z.number().int().nonnegative(),
|
|
2505
|
+
validFromMs: import_zod9.z.number().int().nonnegative(),
|
|
2506
|
+
validUntilMs: import_zod9.z.number().int().positive(),
|
|
2507
|
+
state: import_zod9.z.enum(PASS_STATES),
|
|
2508
|
+
metadata: PassMetadataSchema,
|
|
2509
|
+
nonce: import_zod9.z.string().min(1),
|
|
2510
|
+
/** Device id this pass is bound to (FK to backend `device_keys`). */
|
|
2511
|
+
holderDeviceId: import_zod9.z.string().min(1),
|
|
2512
|
+
/** 32-byte hex Ed25519 public key of the bound device. The redemption signature
|
|
2513
|
+
* is verified against this key — it is the security-critical binding. */
|
|
2514
|
+
holderDevicePubkey: HexString2(32),
|
|
2515
|
+
/** Optional fixed amount for monetary passes (vouchers, gift cards) in kobo. */
|
|
2516
|
+
amountKobo: import_zod9.z.number().int().nonnegative().optional(),
|
|
2517
|
+
/** ISO-4217-ish currency code; required on the wire. SDK builders default to NGN. */
|
|
2518
|
+
currency: import_zod9.z.string().min(3).max(8),
|
|
2519
|
+
/** Monotonic redemption counter floor. Redemption.counter MUST be > counterSeed. */
|
|
2520
|
+
counterSeed: import_zod9.z.number().int().nonnegative(),
|
|
2521
|
+
/** Optional cumulative spend cap in kobo across all redemptions of this pass. */
|
|
2522
|
+
cumulativeCapKobo: import_zod9.z.number().int().nonnegative().optional(),
|
|
2523
|
+
issuerSig: HexString2(64)
|
|
2524
|
+
}).refine((v) => v.validUntilMs > v.validFromMs, {
|
|
2525
|
+
message: "validUntilMs must be greater than validFromMs"
|
|
2526
|
+
});
|
|
2527
|
+
function buildPass(input) {
|
|
2528
|
+
if (input.validUntilMs <= input.validFromMs) {
|
|
2529
|
+
throw new Error("validUntilMs must be greater than validFromMs");
|
|
2530
|
+
}
|
|
2531
|
+
const out = {
|
|
2532
|
+
passId: input.passId,
|
|
2533
|
+
kind: input.kind,
|
|
2534
|
+
issuerId: input.issuerId,
|
|
2535
|
+
issuedAtMs: input.issuedAtMs,
|
|
2536
|
+
validFromMs: input.validFromMs,
|
|
2537
|
+
validUntilMs: input.validUntilMs,
|
|
2538
|
+
state: input.state,
|
|
2539
|
+
metadata: input.metadata,
|
|
2540
|
+
nonce: input.nonce,
|
|
2541
|
+
holderDeviceId: input.holderDeviceId,
|
|
2542
|
+
holderDevicePubkey: input.holderDevicePubkey,
|
|
2543
|
+
currency: input.currency ?? "NGN",
|
|
2544
|
+
counterSeed: input.counterSeed
|
|
2545
|
+
};
|
|
2546
|
+
if (typeof input.templateId === "string") out.templateId = input.templateId;
|
|
2547
|
+
if (typeof input.holderUserId === "string")
|
|
2548
|
+
out.holderUserId = input.holderUserId;
|
|
2549
|
+
if (typeof input.amountKobo === "number") out.amountKobo = input.amountKobo;
|
|
2550
|
+
if (typeof input.cumulativeCapKobo === "number") {
|
|
2551
|
+
out.cumulativeCapKobo = input.cumulativeCapKobo;
|
|
2552
|
+
}
|
|
2553
|
+
return out;
|
|
2554
|
+
}
|
|
2555
|
+
function signPass(unsigned, issuerPrivateKey) {
|
|
2556
|
+
const issuerSig = bytesToHex(
|
|
2557
|
+
sign(canonicalJSONBytes(unsigned), issuerPrivateKey)
|
|
2558
|
+
);
|
|
2559
|
+
return { ...unsigned, issuerSig };
|
|
2560
|
+
}
|
|
2561
|
+
function verifyPass(pass, issuerPublicKey) {
|
|
2562
|
+
try {
|
|
2563
|
+
const parsed = PassSchema.parse(pass);
|
|
2564
|
+
const { issuerSig, ...unsigned } = parsed;
|
|
2565
|
+
return verify(
|
|
2566
|
+
canonicalJSONBytes(unsigned),
|
|
2567
|
+
hexToBytes(issuerSig),
|
|
2568
|
+
issuerPublicKey
|
|
2569
|
+
);
|
|
2570
|
+
} catch {
|
|
2571
|
+
return false;
|
|
2572
|
+
}
|
|
2573
|
+
}
|
|
2574
|
+
function isPassWithinValidity(pass, nowMs) {
|
|
2575
|
+
return nowMs >= pass.validFromMs && nowMs < pass.validUntilMs;
|
|
2576
|
+
}
|
|
2577
|
+
|
|
2578
|
+
// src/passes/redemption.ts
|
|
2579
|
+
var import_zod10 = require("zod");
|
|
2580
|
+
var HexSig2 = import_zod10.z.string().regex(/^[0-9a-fA-F]{128}$/, "expected 64-byte hex signature");
|
|
2581
|
+
var RedemptionSchema = import_zod10.z.object({
|
|
2582
|
+
pass: PassSchema,
|
|
2583
|
+
redeemerId: import_zod10.z.string().min(1),
|
|
2584
|
+
redeemedAtMs: import_zod10.z.number().int().nonnegative(),
|
|
2585
|
+
/** Strictly monotonic counter scoped to a single pass. Must be > pass.counterSeed
|
|
2586
|
+
* and > the redeemer's lastSeenCounter for this pass. */
|
|
2587
|
+
counter: import_zod10.z.number().int().positive(),
|
|
2588
|
+
/** Amount being redeemed in kobo (0 for non-monetary passes like ride tickets). */
|
|
2589
|
+
amountKobo: import_zod10.z.number().int().nonnegative(),
|
|
2590
|
+
nonce: import_zod10.z.string().min(1),
|
|
2591
|
+
holderSig: HexSig2
|
|
2592
|
+
});
|
|
2593
|
+
var REDEEMABLE_STATES = /* @__PURE__ */ new Set(["issued", "active"]);
|
|
2594
|
+
function buildRedemption(input) {
|
|
2595
|
+
if (!REDEEMABLE_STATES.has(input.pass.state)) {
|
|
2596
|
+
throw new Error(`pass not in redeemable state: ${input.pass.state}`);
|
|
2597
|
+
}
|
|
1962
2598
|
if (input.redeemedAtMs < input.pass.validFromMs) {
|
|
1963
2599
|
throw new Error("redeemedAtMs is before pass validFromMs");
|
|
1964
2600
|
}
|
|
@@ -2037,43 +2673,43 @@ function verifyRedemption(r, issuerPublicKey) {
|
|
|
2037
2673
|
}
|
|
2038
2674
|
|
|
2039
2675
|
// src/receipts/receipt.ts
|
|
2040
|
-
var
|
|
2676
|
+
var import_zod11 = require("zod");
|
|
2041
2677
|
var RECEIPT_CHANNELS = ["cash", "pass"];
|
|
2042
2678
|
var RECEIPT_KINDS = RECEIPT_CHANNELS;
|
|
2043
|
-
var HexString3 = (length) =>
|
|
2679
|
+
var HexString3 = (length) => import_zod11.z.string().regex(
|
|
2044
2680
|
new RegExp(`^[0-9a-fA-F]{${length * 2}}$`),
|
|
2045
2681
|
`expected ${length}-byte hex string`
|
|
2046
2682
|
);
|
|
2047
|
-
var ReceiptPayloadSchema =
|
|
2048
|
-
|
|
2683
|
+
var ReceiptPayloadSchema = import_zod11.z.record(
|
|
2684
|
+
import_zod11.z.union([import_zod11.z.string(), import_zod11.z.number(), import_zod11.z.boolean(), import_zod11.z.null()])
|
|
2049
2685
|
);
|
|
2050
|
-
var ReceiptSchema =
|
|
2051
|
-
receiptId:
|
|
2052
|
-
channel:
|
|
2686
|
+
var ReceiptSchema = import_zod11.z.object({
|
|
2687
|
+
receiptId: import_zod11.z.string().min(1),
|
|
2688
|
+
channel: import_zod11.z.enum(RECEIPT_CHANNELS),
|
|
2053
2689
|
/** Cash-channel: send_intents.id. Required when channel === 'cash'. */
|
|
2054
|
-
intentId:
|
|
2690
|
+
intentId: import_zod11.z.string().min(1).optional(),
|
|
2055
2691
|
/** Pass-channel: pass_redemptions.id. Required when channel === 'pass'. */
|
|
2056
|
-
passRedemptionId:
|
|
2057
|
-
payerUserId:
|
|
2058
|
-
payeeUserId:
|
|
2059
|
-
amountKobo:
|
|
2060
|
-
currency:
|
|
2061
|
-
issuedAtMs:
|
|
2062
|
-
issuerId:
|
|
2692
|
+
passRedemptionId: import_zod11.z.string().min(1).optional(),
|
|
2693
|
+
payerUserId: import_zod11.z.string().min(1),
|
|
2694
|
+
payeeUserId: import_zod11.z.string().min(1),
|
|
2695
|
+
amountKobo: import_zod11.z.number().int().nonnegative(),
|
|
2696
|
+
currency: import_zod11.z.string().min(3).max(8),
|
|
2697
|
+
issuedAtMs: import_zod11.z.number().int().nonnegative(),
|
|
2698
|
+
issuerId: import_zod11.z.string().min(1),
|
|
2063
2699
|
payload: ReceiptPayloadSchema,
|
|
2064
2700
|
issuerSig: HexString3(64)
|
|
2065
2701
|
}).superRefine((v, ctx) => {
|
|
2066
2702
|
if (v.channel === "cash") {
|
|
2067
2703
|
if (!v.intentId) {
|
|
2068
2704
|
ctx.addIssue({
|
|
2069
|
-
code:
|
|
2705
|
+
code: import_zod11.z.ZodIssueCode.custom,
|
|
2070
2706
|
message: "cash receipts require intentId",
|
|
2071
2707
|
path: ["intentId"]
|
|
2072
2708
|
});
|
|
2073
2709
|
}
|
|
2074
2710
|
if (v.passRedemptionId) {
|
|
2075
2711
|
ctx.addIssue({
|
|
2076
|
-
code:
|
|
2712
|
+
code: import_zod11.z.ZodIssueCode.custom,
|
|
2077
2713
|
message: "cash receipts must not carry passRedemptionId",
|
|
2078
2714
|
path: ["passRedemptionId"]
|
|
2079
2715
|
});
|
|
@@ -2081,14 +2717,14 @@ var ReceiptSchema = import_zod9.z.object({
|
|
|
2081
2717
|
} else if (v.channel === "pass") {
|
|
2082
2718
|
if (!v.passRedemptionId) {
|
|
2083
2719
|
ctx.addIssue({
|
|
2084
|
-
code:
|
|
2720
|
+
code: import_zod11.z.ZodIssueCode.custom,
|
|
2085
2721
|
message: "pass receipts require passRedemptionId",
|
|
2086
2722
|
path: ["passRedemptionId"]
|
|
2087
2723
|
});
|
|
2088
2724
|
}
|
|
2089
2725
|
if (v.intentId) {
|
|
2090
2726
|
ctx.addIssue({
|
|
2091
|
-
code:
|
|
2727
|
+
code: import_zod11.z.ZodIssueCode.custom,
|
|
2092
2728
|
message: "pass receipts must not carry intentId",
|
|
2093
2729
|
path: ["intentId"]
|
|
2094
2730
|
});
|
|
@@ -2327,317 +2963,90 @@ function createReceiptsClient(opts) {
|
|
|
2327
2963
|
verifyReceipt: (receipt, issuerPublicKey) => verifyReceipt(receipt, issuerPublicKey)
|
|
2328
2964
|
};
|
|
2329
2965
|
}
|
|
2330
|
-
|
|
2331
|
-
// src/client/flur.ts
|
|
2332
|
-
function generateStaticQR(input) {
|
|
2333
|
-
return encodeNQR({ ...input, pointOfInitiation: "static" });
|
|
2334
|
-
}
|
|
2335
|
-
function generateDynamicQR(input) {
|
|
2336
|
-
return encodeNQR({ ...input, pointOfInitiation: "dynamic" });
|
|
2337
|
-
}
|
|
2338
|
-
function parseQR(payload) {
|
|
2339
|
-
return parseNQR(payload);
|
|
2340
|
-
}
|
|
2341
|
-
function init(opts) {
|
|
2342
|
-
const signedFetch = createHmacFetch({
|
|
2343
|
-
apiKey: opts.apiKey,
|
|
2344
|
-
apiSecret: opts.apiSecret,
|
|
2345
|
-
fetchImpl: opts.fetchImpl,
|
|
2346
|
-
scope: opts.scope
|
|
2347
|
-
});
|
|
2348
|
-
const baseUrl = opts.baseUrl.replace(/\/$/, "");
|
|
2349
|
-
function subscribeToPayments(s) {
|
|
2350
|
-
const controller = new AbortController();
|
|
2351
|
-
let cancelled = false;
|
|
2352
|
-
(async () => {
|
|
2353
|
-
try {
|
|
2354
|
-
const url = `${baseUrl}/v1/payments/subscribe?reference=${encodeURIComponent(s.reference)}`;
|
|
2355
|
-
const resp = await signedFetch(url, {
|
|
2356
|
-
method: "GET",
|
|
2357
|
-
headers: { accept: "text/event-stream" },
|
|
2358
|
-
signal: controller.signal
|
|
2359
|
-
});
|
|
2360
|
-
if (!resp.body) return;
|
|
2361
|
-
const reader = resp.body.getReader();
|
|
2362
|
-
const decoder = new TextDecoder();
|
|
2363
|
-
let buffer = "";
|
|
2364
|
-
while (!cancelled) {
|
|
2365
|
-
const { value, done } = await reader.read();
|
|
2366
|
-
if (done) return;
|
|
2367
|
-
buffer += decoder.decode(value, { stream: true });
|
|
2368
|
-
let idx;
|
|
2369
|
-
while ((idx = buffer.indexOf("\n\n")) >= 0) {
|
|
2370
|
-
const chunk = buffer.slice(0, idx);
|
|
2371
|
-
buffer = buffer.slice(idx + 2);
|
|
2372
|
-
for (const line of chunk.split("\n")) {
|
|
2373
|
-
if (!line.startsWith("data:")) continue;
|
|
2374
|
-
const json = line.slice(5).trim();
|
|
2375
|
-
if (!json) continue;
|
|
2376
|
-
try {
|
|
2377
|
-
s.onEvent(JSON.parse(json));
|
|
2378
|
-
} catch (err) {
|
|
2379
|
-
s.onError?.(err);
|
|
2380
|
-
}
|
|
2381
|
-
}
|
|
2382
|
-
}
|
|
2383
|
-
}
|
|
2384
|
-
} catch (err) {
|
|
2385
|
-
if (!cancelled) s.onError?.(err);
|
|
2386
|
-
}
|
|
2387
|
-
})();
|
|
2388
|
-
return () => {
|
|
2389
|
-
cancelled = true;
|
|
2390
|
-
controller.abort();
|
|
2391
|
-
};
|
|
2392
|
-
}
|
|
2393
|
-
const cash = {
|
|
2394
|
-
generateStaticQR,
|
|
2395
|
-
generateDynamicQR,
|
|
2396
|
-
parseQR,
|
|
2397
|
-
subscribeToPayments
|
|
2398
|
-
};
|
|
2399
|
-
const passes = createPassesClient({ baseUrl, fetchImpl: signedFetch });
|
|
2400
|
-
const receipts = createReceiptsClient({ baseUrl, fetchImpl: signedFetch });
|
|
2401
|
-
return {
|
|
2402
|
-
// top-level back-compat surface
|
|
2403
|
-
generateStaticQR,
|
|
2404
|
-
generateDynamicQR,
|
|
2405
|
-
parseQR,
|
|
2406
|
-
subscribeToPayments,
|
|
2407
|
-
// namespaces
|
|
2408
|
-
cash,
|
|
2409
|
-
passes,
|
|
2410
|
-
receipts
|
|
2411
|
-
};
|
|
2412
|
-
}
|
|
2413
|
-
|
|
2414
|
-
// src/accounts/client.ts
|
|
2415
|
-
var import_zod10 = require("zod");
|
|
2416
|
-
var ACCOUNT_TYPES = ["personal", "business", "partner"];
|
|
2417
|
-
var ACCOUNT_STATUSES = ["active", "suspended", "closed"];
|
|
2418
|
-
var MEMBERSHIP_ROLES = ["owner", "admin", "driver", "staff"];
|
|
2419
|
-
var AccountSchema = import_zod10.z.object({
|
|
2420
|
-
accountId: import_zod10.z.string().uuid(),
|
|
2421
|
-
type: import_zod10.z.enum(ACCOUNT_TYPES),
|
|
2422
|
-
displayName: import_zod10.z.string().min(1),
|
|
2423
|
-
status: import_zod10.z.enum(ACCOUNT_STATUSES),
|
|
2424
|
-
ownerUserId: import_zod10.z.string().uuid().nullable(),
|
|
2425
|
-
createdAtMs: import_zod10.z.number().int().nonnegative()
|
|
2426
|
-
});
|
|
2427
|
-
var AccountMembershipSchema = import_zod10.z.object({
|
|
2428
|
-
accountId: import_zod10.z.string().uuid(),
|
|
2429
|
-
userId: import_zod10.z.string().uuid(),
|
|
2430
|
-
role: import_zod10.z.enum(MEMBERSHIP_ROLES),
|
|
2431
|
-
createdAtMs: import_zod10.z.number().int().nonnegative()
|
|
2432
|
-
});
|
|
2433
|
-
function createAccountsClient(opts) {
|
|
2434
|
-
const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
|
|
2435
|
-
if (!fetchImpl) {
|
|
2436
|
-
throw new Error("createAccountsClient: no fetch implementation available");
|
|
2437
|
-
}
|
|
2438
|
-
const baseUrl = opts.baseUrl.replace(/\/$/, "");
|
|
2439
|
-
async function call(method, path, body, parser) {
|
|
2440
|
-
const init2 = {
|
|
2441
|
-
method,
|
|
2442
|
-
headers: {
|
|
2443
|
-
"content-type": "application/json",
|
|
2444
|
-
accept: "application/json"
|
|
2445
|
-
}
|
|
2446
|
-
};
|
|
2447
|
-
if (body !== void 0) init2.body = JSON.stringify(body);
|
|
2448
|
-
const resp = await fetchImpl(`${baseUrl}${path}`, init2);
|
|
2449
|
-
const text = await resp.text();
|
|
2450
|
-
let raw = void 0;
|
|
2451
|
-
if (text) {
|
|
2452
|
-
try {
|
|
2453
|
-
raw = JSON.parse(text);
|
|
2454
|
-
} catch {
|
|
2455
|
-
}
|
|
2456
|
-
}
|
|
2457
|
-
if (!resp.ok) {
|
|
2458
|
-
const code = raw && typeof raw === "object" && "code" in raw && typeof raw.code === "string" ? raw.code : `http_${resp.status}`;
|
|
2459
|
-
const message = raw && typeof raw === "object" && "message" in raw && typeof raw.message === "string" ? raw.message : `request failed with status ${resp.status}`;
|
|
2460
|
-
throw new FlurApiError(resp.status, code, message, raw);
|
|
2461
|
-
}
|
|
2462
|
-
return parser(raw);
|
|
2463
|
-
}
|
|
2464
|
-
const itemsSchema = import_zod10.z.object({ items: import_zod10.z.array(AccountSchema) });
|
|
2465
|
-
const memberItemsSchema = import_zod10.z.object({
|
|
2466
|
-
items: import_zod10.z.array(AccountMembershipSchema)
|
|
2467
|
-
});
|
|
2468
|
-
return {
|
|
2469
|
-
listMyAccounts: () => call(
|
|
2470
|
-
"GET",
|
|
2471
|
-
"/v1/accounts/me",
|
|
2472
|
-
void 0,
|
|
2473
|
-
(raw) => itemsSchema.parse(raw)
|
|
2474
|
-
),
|
|
2475
|
-
getAccount: (accountId) => call(
|
|
2476
|
-
"GET",
|
|
2477
|
-
`/v1/accounts/${encodeURIComponent(accountId)}`,
|
|
2478
|
-
void 0,
|
|
2479
|
-
(raw) => AccountSchema.parse(raw)
|
|
2480
|
-
),
|
|
2481
|
-
listMembers: (accountId) => call(
|
|
2482
|
-
"GET",
|
|
2483
|
-
`/v1/accounts/${encodeURIComponent(accountId)}/members`,
|
|
2484
|
-
void 0,
|
|
2485
|
-
(raw) => memberItemsSchema.parse(raw)
|
|
2486
|
-
),
|
|
2487
|
-
createBusinessAccount: (input) => call("POST", "/v1/accounts", input, (raw) => AccountSchema.parse(raw)),
|
|
2488
|
-
addMember: (accountId, input) => call(
|
|
2489
|
-
"POST",
|
|
2490
|
-
`/v1/accounts/${encodeURIComponent(accountId)}/members`,
|
|
2491
|
-
input,
|
|
2492
|
-
(raw) => AccountMembershipSchema.parse(raw)
|
|
2493
|
-
)
|
|
2494
|
-
};
|
|
2495
|
-
}
|
|
2496
|
-
|
|
2497
|
-
// src/partner/client.ts
|
|
2498
|
-
var import_zod11 = require("zod");
|
|
2499
|
-
var import_sha2563 = require("@noble/hashes/sha256");
|
|
2500
|
-
var import_hmac4 = require("@noble/hashes/hmac");
|
|
2501
|
-
var import_utils2 = require("@noble/hashes/utils");
|
|
2502
|
-
var PARTNER_SCOPES = [
|
|
2503
|
-
"passes:write",
|
|
2504
|
-
"passes:read",
|
|
2505
|
-
"passes:redeem",
|
|
2506
|
-
"receipts:write",
|
|
2507
|
-
"receipts:read",
|
|
2508
|
-
"offline:issue",
|
|
2509
|
-
"offline:settle",
|
|
2510
|
-
"offline:read"
|
|
2511
|
-
];
|
|
2512
|
-
var ApiCredentialPublicSchema = import_zod11.z.object({
|
|
2513
|
-
id: import_zod11.z.string().uuid(),
|
|
2514
|
-
accountId: import_zod11.z.string().uuid(),
|
|
2515
|
-
keyId: import_zod11.z.string(),
|
|
2516
|
-
scopes: import_zod11.z.array(import_zod11.z.enum(PARTNER_SCOPES)),
|
|
2517
|
-
label: import_zod11.z.string().nullable(),
|
|
2518
|
-
createdAtMs: import_zod11.z.number().int().nonnegative(),
|
|
2519
|
-
lastUsedAtMs: import_zod11.z.number().int().nonnegative().nullable(),
|
|
2520
|
-
revokedAtMs: import_zod11.z.number().int().nonnegative().nullable()
|
|
2521
|
-
});
|
|
2522
|
-
var MintedApiCredentialSchema = ApiCredentialPublicSchema.extend({
|
|
2523
|
-
secret: import_zod11.z.string().min(1)
|
|
2524
|
-
});
|
|
2525
|
-
var enc = new TextEncoder();
|
|
2526
|
-
async function sha256Hex2(input) {
|
|
2527
|
-
const data = typeof input === "string" ? enc.encode(input) : input;
|
|
2528
|
-
return (0, import_utils2.bytesToHex)((0, import_sha2563.sha256)(data));
|
|
2529
|
-
}
|
|
2530
|
-
async function hmacSha256Hex(keyHex, message) {
|
|
2531
|
-
return (0, import_utils2.bytesToHex)((0, import_hmac4.hmac)(import_sha2563.sha256, enc.encode(keyHex), enc.encode(message)));
|
|
2532
|
-
}
|
|
2533
|
-
function defaultNonce2() {
|
|
2534
|
-
const c = globalThis.crypto;
|
|
2535
|
-
if (c?.randomUUID) return c.randomUUID();
|
|
2536
|
-
return `${Date.now().toString(16)}-${Math.random().toString(16).slice(2)}`;
|
|
2537
|
-
}
|
|
2538
|
-
function canonical(params) {
|
|
2539
|
-
return [
|
|
2540
|
-
params.method.toUpperCase(),
|
|
2541
|
-
params.path,
|
|
2542
|
-
params.ts,
|
|
2543
|
-
params.nonce,
|
|
2544
|
-
params.bodyHash
|
|
2545
|
-
].join("\n");
|
|
2546
|
-
}
|
|
2547
|
-
async function signPartnerRequest(params) {
|
|
2548
|
-
const ts = String(Math.floor((params.nowMs ?? Date.now()) / 1e3));
|
|
2549
|
-
const nonce = params.nonce ?? defaultNonce2();
|
|
2550
|
-
const bodyData = typeof params.body === "string" ? enc.encode(params.body) : params.body ?? new Uint8Array();
|
|
2551
|
-
const bodyHash = await sha256Hex2(bodyData);
|
|
2552
|
-
const message = canonical({
|
|
2553
|
-
method: params.method,
|
|
2554
|
-
path: params.path,
|
|
2555
|
-
ts,
|
|
2556
|
-
nonce,
|
|
2557
|
-
bodyHash
|
|
2558
|
-
});
|
|
2559
|
-
const signingKey = await sha256Hex2(params.secret);
|
|
2560
|
-
const sig = await hmacSha256Hex(signingKey, message);
|
|
2561
|
-
return {
|
|
2562
|
-
authorization: `Flur-Hmac key=${params.keyId}, ts=${ts}, nonce=${nonce}, sig=${sig}`,
|
|
2563
|
-
ts,
|
|
2564
|
-
nonce,
|
|
2565
|
-
bodyHash
|
|
2566
|
-
};
|
|
2966
|
+
|
|
2967
|
+
// src/client/flur.ts
|
|
2968
|
+
function generateStaticQR(input) {
|
|
2969
|
+
return encodeNQR({ ...input, pointOfInitiation: "static" });
|
|
2567
2970
|
}
|
|
2568
|
-
function
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2971
|
+
function generateDynamicQR(input) {
|
|
2972
|
+
return encodeNQR({ ...input, pointOfInitiation: "dynamic" });
|
|
2973
|
+
}
|
|
2974
|
+
function parseQR(payload) {
|
|
2975
|
+
return parseNQR(payload);
|
|
2976
|
+
}
|
|
2977
|
+
function init(opts) {
|
|
2978
|
+
const partner = createFlurPartnerClient({
|
|
2979
|
+
baseUrl: opts.baseUrl,
|
|
2980
|
+
keyId: opts.apiKey,
|
|
2981
|
+
secret: opts.apiSecret,
|
|
2982
|
+
fetchImpl: opts.fetchImpl,
|
|
2983
|
+
scope: opts.scope
|
|
2984
|
+
});
|
|
2985
|
+
const signedFetch = partner.fetch;
|
|
2575
2986
|
const baseUrl = opts.baseUrl.replace(/\/$/, "");
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2987
|
+
function subscribeToPayments(s) {
|
|
2988
|
+
let cancelled = false;
|
|
2989
|
+
queueMicrotask(() => {
|
|
2990
|
+
if (cancelled) return;
|
|
2991
|
+
s.onError?.(
|
|
2992
|
+
new Error(
|
|
2993
|
+
"cash.subscribeToPayments is not available on this backend release; use collections reports or provider webhooks for payment status."
|
|
2994
|
+
)
|
|
2995
|
+
);
|
|
2585
2996
|
});
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
accept: "application/json"
|
|
2997
|
+
return () => {
|
|
2998
|
+
cancelled = true;
|
|
2589
2999
|
};
|
|
2590
|
-
if (body !== void 0) headers["content-type"] = "application/json";
|
|
2591
|
-
const init2 = { method, headers };
|
|
2592
|
-
if (body !== void 0) init2.body = body;
|
|
2593
|
-
return init2;
|
|
2594
|
-
}
|
|
2595
|
-
async function request(opts2) {
|
|
2596
|
-
const bodyStr = opts2.body === void 0 ? void 0 : JSON.stringify(opts2.body);
|
|
2597
|
-
const init2 = await makeSignedInit(opts2.method, opts2.path, bodyStr);
|
|
2598
|
-
const resp = await fetchImpl(`${baseUrl}${opts2.path}`, init2);
|
|
2599
|
-
const text = await resp.text();
|
|
2600
|
-
let raw;
|
|
2601
|
-
if (text) {
|
|
2602
|
-
try {
|
|
2603
|
-
raw = JSON.parse(text);
|
|
2604
|
-
} catch {
|
|
2605
|
-
}
|
|
2606
|
-
}
|
|
2607
|
-
if (!resp.ok) {
|
|
2608
|
-
const code = raw && typeof raw === "object" && "code" in raw && typeof raw.code === "string" ? raw.code : `http_${resp.status}`;
|
|
2609
|
-
const message = raw && typeof raw === "object" && "message" in raw && typeof raw.message === "string" ? raw.message : `request failed with status ${resp.status}`;
|
|
2610
|
-
throw new FlurApiError(resp.status, code, message, raw);
|
|
2611
|
-
}
|
|
2612
|
-
return raw;
|
|
2613
3000
|
}
|
|
2614
|
-
const
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
3001
|
+
const cash = {
|
|
3002
|
+
generateStaticQR,
|
|
3003
|
+
generateDynamicQR,
|
|
3004
|
+
parseQR,
|
|
3005
|
+
subscribeToPayments
|
|
3006
|
+
};
|
|
3007
|
+
const passes = createPassesClient({ baseUrl, fetchImpl: signedFetch });
|
|
3008
|
+
const receipts = createReceiptsClient({ baseUrl, fetchImpl: signedFetch });
|
|
3009
|
+
const collections = createPartnerCollectionsClient({
|
|
3010
|
+
baseUrl,
|
|
3011
|
+
fetchImpl: signedFetch
|
|
3012
|
+
});
|
|
3013
|
+
return {
|
|
3014
|
+
// top-level back-compat surface
|
|
3015
|
+
generateStaticQR,
|
|
3016
|
+
generateDynamicQR,
|
|
3017
|
+
parseQR,
|
|
3018
|
+
subscribeToPayments,
|
|
3019
|
+
// namespaces
|
|
3020
|
+
cash,
|
|
3021
|
+
collections,
|
|
3022
|
+
passes,
|
|
3023
|
+
receipts
|
|
2632
3024
|
};
|
|
2633
|
-
return { request, fetch: fetchLike };
|
|
2634
3025
|
}
|
|
2635
|
-
|
|
3026
|
+
|
|
3027
|
+
// src/accounts/client.ts
|
|
3028
|
+
var import_zod12 = require("zod");
|
|
3029
|
+
var ACCOUNT_TYPES = ["personal", "business", "partner"];
|
|
3030
|
+
var ACCOUNT_STATUSES = ["active", "suspended", "closed"];
|
|
3031
|
+
var MEMBERSHIP_ROLES = ["owner", "admin", "driver", "staff"];
|
|
3032
|
+
var AccountSchema = import_zod12.z.object({
|
|
3033
|
+
accountId: import_zod12.z.string().uuid(),
|
|
3034
|
+
type: import_zod12.z.enum(ACCOUNT_TYPES),
|
|
3035
|
+
displayName: import_zod12.z.string().min(1),
|
|
3036
|
+
status: import_zod12.z.enum(ACCOUNT_STATUSES),
|
|
3037
|
+
ownerUserId: import_zod12.z.string().uuid().nullable(),
|
|
3038
|
+
createdAtMs: import_zod12.z.number().int().nonnegative()
|
|
3039
|
+
});
|
|
3040
|
+
var AccountMembershipSchema = import_zod12.z.object({
|
|
3041
|
+
accountId: import_zod12.z.string().uuid(),
|
|
3042
|
+
userId: import_zod12.z.string().uuid(),
|
|
3043
|
+
role: import_zod12.z.enum(MEMBERSHIP_ROLES),
|
|
3044
|
+
createdAtMs: import_zod12.z.number().int().nonnegative()
|
|
3045
|
+
});
|
|
3046
|
+
function createAccountsClient(opts) {
|
|
2636
3047
|
const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
|
|
2637
3048
|
if (!fetchImpl) {
|
|
2638
|
-
throw new Error(
|
|
2639
|
-
"createApiCredentialsAdminClient: no fetch implementation available"
|
|
2640
|
-
);
|
|
3049
|
+
throw new Error("createAccountsClient: no fetch implementation available");
|
|
2641
3050
|
}
|
|
2642
3051
|
const baseUrl = opts.baseUrl.replace(/\/$/, "");
|
|
2643
3052
|
async function call(method, path, body, parser) {
|
|
@@ -2651,7 +3060,7 @@ function createApiCredentialsAdminClient(opts) {
|
|
|
2651
3060
|
if (body !== void 0) init2.body = JSON.stringify(body);
|
|
2652
3061
|
const resp = await fetchImpl(`${baseUrl}${path}`, init2);
|
|
2653
3062
|
const text = await resp.text();
|
|
2654
|
-
let raw;
|
|
3063
|
+
let raw = void 0;
|
|
2655
3064
|
if (text) {
|
|
2656
3065
|
try {
|
|
2657
3066
|
raw = JSON.parse(text);
|
|
@@ -2665,70 +3074,78 @@ function createApiCredentialsAdminClient(opts) {
|
|
|
2665
3074
|
}
|
|
2666
3075
|
return parser(raw);
|
|
2667
3076
|
}
|
|
2668
|
-
const
|
|
2669
|
-
|
|
3077
|
+
const itemsSchema = import_zod12.z.object({ items: import_zod12.z.array(AccountSchema) });
|
|
3078
|
+
const memberItemsSchema = import_zod12.z.object({
|
|
3079
|
+
items: import_zod12.z.array(AccountMembershipSchema)
|
|
2670
3080
|
});
|
|
2671
3081
|
return {
|
|
2672
|
-
|
|
3082
|
+
listMyAccounts: () => call(
|
|
2673
3083
|
"GET",
|
|
2674
|
-
|
|
3084
|
+
"/v1/accounts/me",
|
|
2675
3085
|
void 0,
|
|
2676
|
-
(raw) =>
|
|
3086
|
+
(raw) => itemsSchema.parse(raw)
|
|
2677
3087
|
),
|
|
2678
|
-
|
|
2679
|
-
"
|
|
2680
|
-
`/v1/accounts/${accountId}
|
|
2681
|
-
|
|
2682
|
-
(raw) =>
|
|
3088
|
+
getAccount: (accountId) => call(
|
|
3089
|
+
"GET",
|
|
3090
|
+
`/v1/accounts/${encodeURIComponent(accountId)}`,
|
|
3091
|
+
void 0,
|
|
3092
|
+
(raw) => AccountSchema.parse(raw)
|
|
2683
3093
|
),
|
|
2684
|
-
|
|
2685
|
-
"
|
|
2686
|
-
`/v1/accounts/${accountId}/
|
|
3094
|
+
listMembers: (accountId) => call(
|
|
3095
|
+
"GET",
|
|
3096
|
+
`/v1/accounts/${encodeURIComponent(accountId)}/members`,
|
|
2687
3097
|
void 0,
|
|
2688
|
-
(raw) =>
|
|
3098
|
+
(raw) => memberItemsSchema.parse(raw)
|
|
3099
|
+
),
|
|
3100
|
+
createBusinessAccount: (input) => call("POST", "/v1/accounts", input, (raw) => AccountSchema.parse(raw)),
|
|
3101
|
+
addMember: (accountId, input) => call(
|
|
3102
|
+
"POST",
|
|
3103
|
+
`/v1/accounts/${encodeURIComponent(accountId)}/members`,
|
|
3104
|
+
input,
|
|
3105
|
+
(raw) => AccountMembershipSchema.parse(raw)
|
|
2689
3106
|
)
|
|
2690
3107
|
};
|
|
2691
3108
|
}
|
|
2692
3109
|
|
|
2693
3110
|
// src/me-offline/client.ts
|
|
2694
|
-
var
|
|
2695
|
-
var Hex64 =
|
|
2696
|
-
var HexAny =
|
|
2697
|
-
var Sha256Hex =
|
|
2698
|
-
var RegisterDeviceKeyInputSchema =
|
|
2699
|
-
deviceId:
|
|
3111
|
+
var import_zod13 = require("zod");
|
|
3112
|
+
var Hex64 = import_zod13.z.string().regex(/^[0-9a-f]{64}$/i);
|
|
3113
|
+
var HexAny = import_zod13.z.string().regex(/^[0-9a-f]+$/i);
|
|
3114
|
+
var Sha256Hex = import_zod13.z.string().regex(/^[0-9a-f]{64}$/i);
|
|
3115
|
+
var RegisterDeviceKeyInputSchema = import_zod13.z.object({
|
|
3116
|
+
deviceId: import_zod13.z.string().min(1).max(128),
|
|
2700
3117
|
publicKeyHex: Hex64
|
|
2701
3118
|
});
|
|
2702
|
-
var DeviceKeyRecordSchema =
|
|
2703
|
-
id:
|
|
2704
|
-
userId:
|
|
2705
|
-
deviceId:
|
|
3119
|
+
var DeviceKeyRecordSchema = import_zod13.z.object({
|
|
3120
|
+
id: import_zod13.z.string().uuid(),
|
|
3121
|
+
userId: import_zod13.z.string().uuid(),
|
|
3122
|
+
deviceId: import_zod13.z.string(),
|
|
2706
3123
|
publicKeyHex: Hex64,
|
|
2707
|
-
createdAtMs:
|
|
2708
|
-
revokedAtMs:
|
|
3124
|
+
createdAtMs: import_zod13.z.number().int().nonnegative(),
|
|
3125
|
+
revokedAtMs: import_zod13.z.number().int().nonnegative().nullable()
|
|
2709
3126
|
});
|
|
2710
|
-
var ConsumerOACSchema =
|
|
2711
|
-
oacId:
|
|
2712
|
-
issuerId:
|
|
2713
|
-
userId:
|
|
2714
|
-
deviceId:
|
|
3127
|
+
var ConsumerOACSchema = import_zod13.z.object({
|
|
3128
|
+
oacId: import_zod13.z.string().uuid(),
|
|
3129
|
+
issuerId: import_zod13.z.string().min(1).max(64),
|
|
3130
|
+
userId: import_zod13.z.string().uuid(),
|
|
3131
|
+
deviceId: import_zod13.z.string().min(1).max(128),
|
|
2715
3132
|
devicePubkeyHex: Hex64,
|
|
2716
|
-
perTxCapKobo:
|
|
2717
|
-
cumulativeCapKobo:
|
|
2718
|
-
currency:
|
|
2719
|
-
validFromMs:
|
|
2720
|
-
validUntilMs:
|
|
2721
|
-
counterSeed:
|
|
2722
|
-
issuedAtMs:
|
|
2723
|
-
});
|
|
2724
|
-
var SignedConsumerOACSchema =
|
|
3133
|
+
perTxCapKobo: import_zod13.z.number().int().positive(),
|
|
3134
|
+
cumulativeCapKobo: import_zod13.z.number().int().positive(),
|
|
3135
|
+
currency: import_zod13.z.string().length(3),
|
|
3136
|
+
validFromMs: import_zod13.z.number().int().nonnegative(),
|
|
3137
|
+
validUntilMs: import_zod13.z.number().int().nonnegative(),
|
|
3138
|
+
counterSeed: import_zod13.z.number().int().nonnegative(),
|
|
3139
|
+
issuedAtMs: import_zod13.z.number().int().nonnegative()
|
|
3140
|
+
});
|
|
3141
|
+
var SignedConsumerOACSchema = import_zod13.z.object({
|
|
2725
3142
|
oac: ConsumerOACSchema,
|
|
2726
3143
|
issuerSig: HexAny,
|
|
2727
3144
|
issuerPublicKeyHex: Hex64
|
|
2728
3145
|
});
|
|
2729
3146
|
var OACRecordSchema = SignedConsumerOACSchema.extend({
|
|
2730
|
-
currentOfflineSpentKobo:
|
|
2731
|
-
status:
|
|
3147
|
+
currentOfflineSpentKobo: import_zod13.z.number().int().nonnegative(),
|
|
3148
|
+
status: import_zod13.z.enum([
|
|
2732
3149
|
"active",
|
|
2733
3150
|
"superseded",
|
|
2734
3151
|
"expired",
|
|
@@ -2737,43 +3154,43 @@ var OACRecordSchema = SignedConsumerOACSchema.extend({
|
|
|
2737
3154
|
"draining",
|
|
2738
3155
|
"closed"
|
|
2739
3156
|
]),
|
|
2740
|
-
supersededAtMs:
|
|
2741
|
-
revokedAtMs:
|
|
2742
|
-
holdId:
|
|
2743
|
-
});
|
|
2744
|
-
var IssueOACInputSchema =
|
|
2745
|
-
deviceId:
|
|
2746
|
-
perTxCapKobo:
|
|
2747
|
-
cumulativeCapKobo:
|
|
2748
|
-
ttlMs:
|
|
2749
|
-
spendableOnlineKobo:
|
|
2750
|
-
});
|
|
2751
|
-
var EnableOfflineInputSchema =
|
|
2752
|
-
deviceId:
|
|
2753
|
-
amountKobo:
|
|
2754
|
-
perTxCapKobo:
|
|
2755
|
-
ttlMs:
|
|
2756
|
-
installId:
|
|
2757
|
-
partnerId:
|
|
2758
|
-
});
|
|
2759
|
-
var DisableOfflineInputSchema =
|
|
2760
|
-
deviceId:
|
|
2761
|
-
installId:
|
|
2762
|
-
claims:
|
|
2763
|
-
});
|
|
2764
|
-
var OfflineHoldRecordSchema =
|
|
2765
|
-
holdId:
|
|
2766
|
-
userId:
|
|
2767
|
-
deviceId:
|
|
2768
|
-
partnerId:
|
|
2769
|
-
adapterKind:
|
|
2770
|
-
externalHoldRef:
|
|
2771
|
-
amountKobo:
|
|
2772
|
-
capturedKobo:
|
|
2773
|
-
releasedKobo:
|
|
2774
|
-
remainingKobo:
|
|
2775
|
-
currency:
|
|
2776
|
-
status:
|
|
3157
|
+
supersededAtMs: import_zod13.z.number().int().nonnegative().nullable(),
|
|
3158
|
+
revokedAtMs: import_zod13.z.number().int().nonnegative().nullable(),
|
|
3159
|
+
holdId: import_zod13.z.string().uuid().nullable().optional()
|
|
3160
|
+
});
|
|
3161
|
+
var IssueOACInputSchema = import_zod13.z.object({
|
|
3162
|
+
deviceId: import_zod13.z.string().min(1).max(128),
|
|
3163
|
+
perTxCapKobo: import_zod13.z.number().int().positive().optional(),
|
|
3164
|
+
cumulativeCapKobo: import_zod13.z.number().int().positive().optional(),
|
|
3165
|
+
ttlMs: import_zod13.z.number().int().min(6e4).max(1e3 * 60 * 60 * 24 * 7).optional(),
|
|
3166
|
+
spendableOnlineKobo: import_zod13.z.number().int().nonnegative().optional()
|
|
3167
|
+
});
|
|
3168
|
+
var EnableOfflineInputSchema = import_zod13.z.object({
|
|
3169
|
+
deviceId: import_zod13.z.string().min(1).max(128),
|
|
3170
|
+
amountKobo: import_zod13.z.number().int().positive(),
|
|
3171
|
+
perTxCapKobo: import_zod13.z.number().int().positive().optional(),
|
|
3172
|
+
ttlMs: import_zod13.z.number().int().min(6e4).max(1e3 * 60 * 60 * 24 * 7).optional(),
|
|
3173
|
+
installId: import_zod13.z.string().min(1).max(128),
|
|
3174
|
+
partnerId: import_zod13.z.string().min(1).max(64).optional()
|
|
3175
|
+
});
|
|
3176
|
+
var DisableOfflineInputSchema = import_zod13.z.object({
|
|
3177
|
+
deviceId: import_zod13.z.string().min(1).max(128),
|
|
3178
|
+
installId: import_zod13.z.string().min(1).max(128).optional(),
|
|
3179
|
+
claims: import_zod13.z.array(import_zod13.z.unknown()).max(256).optional()
|
|
3180
|
+
});
|
|
3181
|
+
var OfflineHoldRecordSchema = import_zod13.z.object({
|
|
3182
|
+
holdId: import_zod13.z.string().uuid(),
|
|
3183
|
+
userId: import_zod13.z.string().uuid(),
|
|
3184
|
+
deviceId: import_zod13.z.string(),
|
|
3185
|
+
partnerId: import_zod13.z.string(),
|
|
3186
|
+
adapterKind: import_zod13.z.string(),
|
|
3187
|
+
externalHoldRef: import_zod13.z.string().nullable(),
|
|
3188
|
+
amountKobo: import_zod13.z.number().int().nonnegative(),
|
|
3189
|
+
capturedKobo: import_zod13.z.number().int().nonnegative(),
|
|
3190
|
+
releasedKobo: import_zod13.z.number().int().nonnegative(),
|
|
3191
|
+
remainingKobo: import_zod13.z.number().int().nonnegative(),
|
|
3192
|
+
currency: import_zod13.z.string().length(3),
|
|
3193
|
+
status: import_zod13.z.enum([
|
|
2777
3194
|
"placing",
|
|
2778
3195
|
"active",
|
|
2779
3196
|
"disabling",
|
|
@@ -2782,71 +3199,71 @@ var OfflineHoldRecordSchema = import_zod12.z.object({
|
|
|
2782
3199
|
"revoked",
|
|
2783
3200
|
"failed"
|
|
2784
3201
|
]),
|
|
2785
|
-
installId:
|
|
2786
|
-
drainDeadlineMs:
|
|
2787
|
-
disableRequestedAtMs:
|
|
2788
|
-
createdAtMs:
|
|
2789
|
-
closedAtMs:
|
|
2790
|
-
isTrusted:
|
|
2791
|
-
});
|
|
2792
|
-
var EnableOfflineResultSchema =
|
|
3202
|
+
installId: import_zod13.z.string().nullable(),
|
|
3203
|
+
drainDeadlineMs: import_zod13.z.number().int().nonnegative(),
|
|
3204
|
+
disableRequestedAtMs: import_zod13.z.number().int().nonnegative().nullable(),
|
|
3205
|
+
createdAtMs: import_zod13.z.number().int().nonnegative(),
|
|
3206
|
+
closedAtMs: import_zod13.z.number().int().nonnegative().nullable(),
|
|
3207
|
+
isTrusted: import_zod13.z.boolean().optional()
|
|
3208
|
+
});
|
|
3209
|
+
var EnableOfflineResultSchema = import_zod13.z.object({
|
|
2793
3210
|
hold: OfflineHoldRecordSchema,
|
|
2794
3211
|
oac: OACRecordSchema
|
|
2795
3212
|
});
|
|
2796
|
-
var DisableOfflineResultSchema =
|
|
3213
|
+
var DisableOfflineResultSchema = import_zod13.z.object({
|
|
2797
3214
|
hold: OfflineHoldRecordSchema,
|
|
2798
|
-
trusted:
|
|
2799
|
-
settledClaims:
|
|
3215
|
+
trusted: import_zod13.z.boolean(),
|
|
3216
|
+
settledClaims: import_zod13.z.number().int().nonnegative()
|
|
2800
3217
|
});
|
|
2801
|
-
var OfflineStatusResultSchema =
|
|
3218
|
+
var OfflineStatusResultSchema = import_zod13.z.object({
|
|
2802
3219
|
hold: OfflineHoldRecordSchema.nullable(),
|
|
2803
3220
|
active: OACRecordSchema.nullable()
|
|
2804
3221
|
});
|
|
2805
|
-
var OfflineStateResultSchema =
|
|
3222
|
+
var OfflineStateResultSchema = import_zod13.z.object({
|
|
2806
3223
|
active: OACRecordSchema.nullable()
|
|
2807
3224
|
});
|
|
2808
|
-
var ConsumerPaymentClaimSchema =
|
|
2809
|
-
oacId:
|
|
3225
|
+
var ConsumerPaymentClaimSchema = import_zod13.z.object({
|
|
3226
|
+
oacId: import_zod13.z.string().uuid(),
|
|
2810
3227
|
encounterId: Sha256Hex.optional(),
|
|
2811
|
-
payerUserId:
|
|
2812
|
-
payeeUserId:
|
|
2813
|
-
payerDeviceId:
|
|
2814
|
-
payerNonce:
|
|
2815
|
-
payeeNonce:
|
|
2816
|
-
amountKobo:
|
|
2817
|
-
currency:
|
|
2818
|
-
occurredAtMs:
|
|
2819
|
-
completedAtMs:
|
|
2820
|
-
contextId:
|
|
3228
|
+
payerUserId: import_zod13.z.string().uuid(),
|
|
3229
|
+
payeeUserId: import_zod13.z.string().uuid(),
|
|
3230
|
+
payerDeviceId: import_zod13.z.string().min(1).max(128),
|
|
3231
|
+
payerNonce: import_zod13.z.string().min(8).max(128),
|
|
3232
|
+
payeeNonce: import_zod13.z.string().min(8).max(128),
|
|
3233
|
+
amountKobo: import_zod13.z.number().int().positive(),
|
|
3234
|
+
currency: import_zod13.z.string().length(3).default("NGN"),
|
|
3235
|
+
occurredAtMs: import_zod13.z.number().int().nonnegative(),
|
|
3236
|
+
completedAtMs: import_zod13.z.number().int().nonnegative().optional(),
|
|
3237
|
+
contextId: import_zod13.z.string().max(128).optional(),
|
|
2821
3238
|
payerPubkeyHex: Hex64,
|
|
2822
3239
|
payerSignature: HexAny,
|
|
2823
3240
|
payeePubkeyHex: Hex64.optional(),
|
|
2824
3241
|
payeeSignature: HexAny.optional()
|
|
2825
3242
|
});
|
|
2826
|
-
var ConsumerSettlementSchema =
|
|
2827
|
-
settlementId:
|
|
3243
|
+
var ConsumerSettlementSchema = import_zod13.z.object({
|
|
3244
|
+
settlementId: import_zod13.z.string().uuid(),
|
|
2828
3245
|
settlementKey: Sha256Hex,
|
|
2829
3246
|
encounterId: Sha256Hex,
|
|
2830
|
-
oacId:
|
|
2831
|
-
payerUserId:
|
|
2832
|
-
payeeUserId:
|
|
2833
|
-
amountKobo:
|
|
2834
|
-
currency:
|
|
2835
|
-
status:
|
|
2836
|
-
reviewReason:
|
|
2837
|
-
ledgerRef:
|
|
3247
|
+
oacId: import_zod13.z.string().uuid(),
|
|
3248
|
+
payerUserId: import_zod13.z.string().uuid(),
|
|
3249
|
+
payeeUserId: import_zod13.z.string().uuid(),
|
|
3250
|
+
amountKobo: import_zod13.z.number().int().positive(),
|
|
3251
|
+
currency: import_zod13.z.string().length(3),
|
|
3252
|
+
status: import_zod13.z.enum(["SETTLED", "REVIEW"]),
|
|
3253
|
+
reviewReason: import_zod13.z.string().nullable(),
|
|
3254
|
+
ledgerRef: import_zod13.z.string().nullable(),
|
|
2838
3255
|
issuerSig: HexAny,
|
|
2839
|
-
createdAtMs:
|
|
3256
|
+
createdAtMs: import_zod13.z.number().int().nonnegative()
|
|
2840
3257
|
});
|
|
2841
|
-
var ConsumerSettleResultSchema =
|
|
3258
|
+
var ConsumerSettleResultSchema = import_zod13.z.object({
|
|
2842
3259
|
settlement: ConsumerSettlementSchema,
|
|
2843
3260
|
encounterId: Sha256Hex,
|
|
2844
|
-
replayed:
|
|
3261
|
+
replayed: import_zod13.z.boolean()
|
|
2845
3262
|
});
|
|
2846
|
-
var RevokeDeviceKeyInputSchema =
|
|
2847
|
-
deviceId:
|
|
3263
|
+
var RevokeDeviceKeyInputSchema = import_zod13.z.object({
|
|
3264
|
+
deviceId: import_zod13.z.string().min(1).max(128),
|
|
2848
3265
|
/** Step-up token from /api/v1/auth/send/verify with purpose='offline_revoke'. */
|
|
2849
|
-
sendAuthToken:
|
|
3266
|
+
sendAuthToken: import_zod13.z.string().min(16)
|
|
2850
3267
|
});
|
|
2851
3268
|
function createMeOfflineClient(opts) {
|
|
2852
3269
|
const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
|
|
@@ -2879,7 +3296,7 @@ function createMeOfflineClient(opts) {
|
|
|
2879
3296
|
}
|
|
2880
3297
|
return parser(raw);
|
|
2881
3298
|
}
|
|
2882
|
-
const deviceKeyItems =
|
|
3299
|
+
const deviceKeyItems = import_zod13.z.object({ items: import_zod13.z.array(DeviceKeyRecordSchema) });
|
|
2883
3300
|
return {
|
|
2884
3301
|
registerDeviceKey: (input) => call(
|
|
2885
3302
|
"POST",
|
|
@@ -2943,6 +3360,320 @@ function createMeOfflineClient(opts) {
|
|
|
2943
3360
|
)
|
|
2944
3361
|
};
|
|
2945
3362
|
}
|
|
3363
|
+
|
|
3364
|
+
// src/partner-funding/client.ts
|
|
3365
|
+
var import_zod14 = require("zod");
|
|
3366
|
+
var MinorString = import_zod14.z.string().regex(/^-?\d+$/);
|
|
3367
|
+
var PositiveMinor = import_zod14.z.union([
|
|
3368
|
+
import_zod14.z.number().int().positive(),
|
|
3369
|
+
import_zod14.z.string().regex(/^[1-9]\d{0,18}$/)
|
|
3370
|
+
]);
|
|
3371
|
+
var Currency = import_zod14.z.string().trim().length(3).transform((v) => v.toUpperCase());
|
|
3372
|
+
var Metadata = import_zod14.z.record(import_zod14.z.unknown());
|
|
3373
|
+
var PARTNER_KINDS = ["bank", "merchant"];
|
|
3374
|
+
var CUSTODIAL_MODES = ["agent_of_bank", "flur_virtual_pool"];
|
|
3375
|
+
var PARTNER_PROFILE_STATUSES = [
|
|
3376
|
+
"active",
|
|
3377
|
+
"suspended",
|
|
3378
|
+
"closed"
|
|
3379
|
+
];
|
|
3380
|
+
var PARTNER_FUNDING_DIRECTIONS = ["credit", "debit"];
|
|
3381
|
+
var PARTNER_FUNDING_STATUSES = [
|
|
3382
|
+
"pending",
|
|
3383
|
+
"posted",
|
|
3384
|
+
"failed"
|
|
3385
|
+
];
|
|
3386
|
+
var PAYOUT_DESTINATION_STATUSES = [
|
|
3387
|
+
"pending",
|
|
3388
|
+
"verified",
|
|
3389
|
+
"disabled"
|
|
3390
|
+
];
|
|
3391
|
+
var WITHDRAWAL_STATES = [
|
|
3392
|
+
"requested",
|
|
3393
|
+
"submitted",
|
|
3394
|
+
"processing",
|
|
3395
|
+
"paid",
|
|
3396
|
+
"failed",
|
|
3397
|
+
"reversed"
|
|
3398
|
+
];
|
|
3399
|
+
var PartnerProfileSchema = import_zod14.z.object({
|
|
3400
|
+
partnerAccountId: import_zod14.z.string().uuid(),
|
|
3401
|
+
kind: import_zod14.z.enum(PARTNER_KINDS),
|
|
3402
|
+
custodialMode: import_zod14.z.enum(CUSTODIAL_MODES),
|
|
3403
|
+
displayName: import_zod14.z.string(),
|
|
3404
|
+
bankCode: import_zod14.z.string().nullable(),
|
|
3405
|
+
poolAccountNumber: import_zod14.z.string().nullable(),
|
|
3406
|
+
status: import_zod14.z.enum(PARTNER_PROFILE_STATUSES),
|
|
3407
|
+
metadata: Metadata,
|
|
3408
|
+
createdAtMs: import_zod14.z.number().int().nonnegative(),
|
|
3409
|
+
updatedAtMs: import_zod14.z.number().int().nonnegative()
|
|
3410
|
+
});
|
|
3411
|
+
var UpsertPartnerProfileInputSchema = import_zod14.z.object({
|
|
3412
|
+
kind: import_zod14.z.enum(PARTNER_KINDS),
|
|
3413
|
+
custodialMode: import_zod14.z.enum(CUSTODIAL_MODES),
|
|
3414
|
+
displayName: import_zod14.z.string().trim().min(1).max(200),
|
|
3415
|
+
bankCode: import_zod14.z.string().trim().min(1).max(64).optional(),
|
|
3416
|
+
poolAccountNumber: import_zod14.z.string().trim().min(1).max(64).optional(),
|
|
3417
|
+
metadata: Metadata.optional()
|
|
3418
|
+
});
|
|
3419
|
+
var PartnerFundingEventInputSchema = import_zod14.z.object({
|
|
3420
|
+
externalRef: import_zod14.z.string().trim().min(8).max(128),
|
|
3421
|
+
direction: import_zod14.z.enum(PARTNER_FUNDING_DIRECTIONS).optional(),
|
|
3422
|
+
userId: import_zod14.z.string().uuid().optional(),
|
|
3423
|
+
accountId: import_zod14.z.string().uuid().optional(),
|
|
3424
|
+
amountMinor: PositiveMinor,
|
|
3425
|
+
currency: Currency,
|
|
3426
|
+
fundingSource: import_zod14.z.string().trim().min(1).max(64).optional(),
|
|
3427
|
+
providerMetadata: Metadata.optional()
|
|
3428
|
+
});
|
|
3429
|
+
var PartnerFundingSchema = import_zod14.z.object({
|
|
3430
|
+
fundingId: import_zod14.z.string().uuid(),
|
|
3431
|
+
partnerId: import_zod14.z.string().uuid(),
|
|
3432
|
+
accountId: import_zod14.z.string().uuid(),
|
|
3433
|
+
userId: import_zod14.z.string().uuid().nullable(),
|
|
3434
|
+
direction: import_zod14.z.enum(PARTNER_FUNDING_DIRECTIONS),
|
|
3435
|
+
currency: import_zod14.z.string(),
|
|
3436
|
+
amountMinor: MinorString,
|
|
3437
|
+
externalRef: import_zod14.z.string(),
|
|
3438
|
+
status: import_zod14.z.enum(PARTNER_FUNDING_STATUSES),
|
|
3439
|
+
fundingSource: import_zod14.z.string(),
|
|
3440
|
+
ledgerRef: import_zod14.z.string(),
|
|
3441
|
+
providerMetadata: Metadata,
|
|
3442
|
+
createdAtMs: import_zod14.z.number().int().nonnegative(),
|
|
3443
|
+
updatedAtMs: import_zod14.z.number().int().nonnegative()
|
|
3444
|
+
});
|
|
3445
|
+
var IngestFundingResultSchema = import_zod14.z.object({
|
|
3446
|
+
funding: PartnerFundingSchema,
|
|
3447
|
+
replayed: import_zod14.z.boolean()
|
|
3448
|
+
});
|
|
3449
|
+
var PayoutDestinationSchema = import_zod14.z.object({
|
|
3450
|
+
destinationId: import_zod14.z.string().uuid(),
|
|
3451
|
+
accountId: import_zod14.z.string().uuid(),
|
|
3452
|
+
partnerId: import_zod14.z.string().uuid(),
|
|
3453
|
+
bankCode: import_zod14.z.string(),
|
|
3454
|
+
accountNumber: import_zod14.z.string(),
|
|
3455
|
+
accountName: import_zod14.z.string(),
|
|
3456
|
+
status: import_zod14.z.enum(PAYOUT_DESTINATION_STATUSES),
|
|
3457
|
+
verifiedAtMs: import_zod14.z.number().int().nonnegative().nullable(),
|
|
3458
|
+
metadata: Metadata,
|
|
3459
|
+
createdAtMs: import_zod14.z.number().int().nonnegative(),
|
|
3460
|
+
updatedAtMs: import_zod14.z.number().int().nonnegative()
|
|
3461
|
+
});
|
|
3462
|
+
var CreatePayoutDestinationInputSchema = import_zod14.z.object({
|
|
3463
|
+
partnerId: import_zod14.z.string().uuid(),
|
|
3464
|
+
bankCode: import_zod14.z.string().trim().min(1).max(32),
|
|
3465
|
+
accountNumber: import_zod14.z.string().trim().min(4).max(64),
|
|
3466
|
+
accountName: import_zod14.z.string().trim().min(1).max(200),
|
|
3467
|
+
metadata: Metadata.optional()
|
|
3468
|
+
});
|
|
3469
|
+
var ListPayoutDestinationsResultSchema = import_zod14.z.object({
|
|
3470
|
+
items: import_zod14.z.array(PayoutDestinationSchema)
|
|
3471
|
+
});
|
|
3472
|
+
var WithdrawalSchema = import_zod14.z.object({
|
|
3473
|
+
withdrawalId: import_zod14.z.string().uuid(),
|
|
3474
|
+
accountId: import_zod14.z.string().uuid(),
|
|
3475
|
+
userId: import_zod14.z.string().uuid(),
|
|
3476
|
+
partnerId: import_zod14.z.string().uuid(),
|
|
3477
|
+
destinationId: import_zod14.z.string().uuid(),
|
|
3478
|
+
currency: import_zod14.z.string(),
|
|
3479
|
+
amountMinor: MinorString,
|
|
3480
|
+
state: import_zod14.z.enum(WITHDRAWAL_STATES),
|
|
3481
|
+
idempotencyKey: import_zod14.z.string(),
|
|
3482
|
+
providerRef: import_zod14.z.string().nullable(),
|
|
3483
|
+
lastError: import_zod14.z.string().nullable(),
|
|
3484
|
+
ledgerRef: import_zod14.z.string(),
|
|
3485
|
+
reverseLedgerRef: import_zod14.z.string().nullable(),
|
|
3486
|
+
metadata: Metadata,
|
|
3487
|
+
createdAtMs: import_zod14.z.number().int().nonnegative(),
|
|
3488
|
+
updatedAtMs: import_zod14.z.number().int().nonnegative()
|
|
3489
|
+
});
|
|
3490
|
+
var CreateWithdrawalInputSchema = import_zod14.z.object({
|
|
3491
|
+
destinationId: import_zod14.z.string().uuid(),
|
|
3492
|
+
amountMinor: PositiveMinor,
|
|
3493
|
+
currency: Currency,
|
|
3494
|
+
idempotencyKey: import_zod14.z.string().trim().min(8).max(128),
|
|
3495
|
+
metadata: Metadata.optional()
|
|
3496
|
+
});
|
|
3497
|
+
var CreateWithdrawalResultSchema = import_zod14.z.object({
|
|
3498
|
+
withdrawal: WithdrawalSchema,
|
|
3499
|
+
replayed: import_zod14.z.boolean()
|
|
3500
|
+
});
|
|
3501
|
+
var PayoutEventInputSchema = import_zod14.z.object({
|
|
3502
|
+
externalRef: import_zod14.z.string().trim().min(8).max(128),
|
|
3503
|
+
withdrawalId: import_zod14.z.string().uuid().optional(),
|
|
3504
|
+
state: import_zod14.z.enum(["submitted", "processing", "paid", "failed"]),
|
|
3505
|
+
providerRef: import_zod14.z.string().trim().min(1).max(128).optional(),
|
|
3506
|
+
failureCode: import_zod14.z.string().trim().max(64).optional(),
|
|
3507
|
+
failureMessage: import_zod14.z.string().trim().max(512).optional(),
|
|
3508
|
+
providerMetadata: Metadata.optional()
|
|
3509
|
+
});
|
|
3510
|
+
var RecordPayoutEventResultSchema = import_zod14.z.object({
|
|
3511
|
+
withdrawal: WithdrawalSchema,
|
|
3512
|
+
replayed: import_zod14.z.boolean()
|
|
3513
|
+
});
|
|
3514
|
+
var ReconciliationReportSchema = import_zod14.z.object({
|
|
3515
|
+
partnerId: import_zod14.z.string().uuid(),
|
|
3516
|
+
currency: import_zod14.z.string(),
|
|
3517
|
+
fromMs: import_zod14.z.number().int().nonnegative(),
|
|
3518
|
+
toMs: import_zod14.z.number().int().nonnegative(),
|
|
3519
|
+
fundingsCreditMinor: MinorString,
|
|
3520
|
+
fundingsDebitMinor: MinorString,
|
|
3521
|
+
withdrawalsPaidMinor: MinorString,
|
|
3522
|
+
withdrawalsReversedMinor: MinorString,
|
|
3523
|
+
withdrawalsInFlightMinor: MinorString,
|
|
3524
|
+
expectedReserveBalanceMinor: MinorString,
|
|
3525
|
+
actualReserveBalanceMinor: MinorString,
|
|
3526
|
+
imbalanceMinor: MinorString,
|
|
3527
|
+
generatedAtMs: import_zod14.z.number().int().nonnegative()
|
|
3528
|
+
});
|
|
3529
|
+
function createPartnerFundingClient(partner) {
|
|
3530
|
+
return {
|
|
3531
|
+
ingestFunding: async (input) => {
|
|
3532
|
+
const body = PartnerFundingEventInputSchema.parse(input);
|
|
3533
|
+
const raw = await partner.request({
|
|
3534
|
+
method: "POST",
|
|
3535
|
+
path: "/v1/partners/fundings",
|
|
3536
|
+
body
|
|
3537
|
+
});
|
|
3538
|
+
return IngestFundingResultSchema.parse(raw);
|
|
3539
|
+
},
|
|
3540
|
+
recordPayoutEvent: async (input) => {
|
|
3541
|
+
const body = PayoutEventInputSchema.parse(input);
|
|
3542
|
+
const raw = await partner.request({
|
|
3543
|
+
method: "POST",
|
|
3544
|
+
path: "/v1/partners/payouts/events",
|
|
3545
|
+
body
|
|
3546
|
+
});
|
|
3547
|
+
return RecordPayoutEventResultSchema.parse(raw);
|
|
3548
|
+
},
|
|
3549
|
+
reconciliation: async (input) => {
|
|
3550
|
+
const qs = new URLSearchParams({
|
|
3551
|
+
currency: input.currency
|
|
3552
|
+
});
|
|
3553
|
+
if (typeof input.fromMs === "number")
|
|
3554
|
+
qs.set("fromMs", String(input.fromMs));
|
|
3555
|
+
if (typeof input.toMs === "number") qs.set("toMs", String(input.toMs));
|
|
3556
|
+
const raw = await partner.request({
|
|
3557
|
+
method: "GET",
|
|
3558
|
+
path: `/v1/partners/reconciliation/daily?${qs.toString()}`
|
|
3559
|
+
});
|
|
3560
|
+
return ReconciliationReportSchema.parse(raw);
|
|
3561
|
+
}
|
|
3562
|
+
};
|
|
3563
|
+
}
|
|
3564
|
+
function createConsumerWithdrawalsClient(opts) {
|
|
3565
|
+
const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
|
|
3566
|
+
if (!fetchImpl) {
|
|
3567
|
+
throw new Error(
|
|
3568
|
+
"createConsumerWithdrawalsClient: no fetch implementation available"
|
|
3569
|
+
);
|
|
3570
|
+
}
|
|
3571
|
+
const baseUrl = opts.baseUrl.replace(/\/$/, "");
|
|
3572
|
+
async function call(method, path, body, parser) {
|
|
3573
|
+
const init2 = {
|
|
3574
|
+
method,
|
|
3575
|
+
headers: { accept: "application/json" }
|
|
3576
|
+
};
|
|
3577
|
+
if (body !== void 0) {
|
|
3578
|
+
init2.body = JSON.stringify(body);
|
|
3579
|
+
init2.headers = { ...init2.headers, "content-type": "application/json" };
|
|
3580
|
+
}
|
|
3581
|
+
const resp = await fetchImpl(`${baseUrl}${path}`, init2);
|
|
3582
|
+
const text = await resp.text();
|
|
3583
|
+
let raw;
|
|
3584
|
+
if (text) {
|
|
3585
|
+
try {
|
|
3586
|
+
raw = JSON.parse(text);
|
|
3587
|
+
} catch {
|
|
3588
|
+
raw = text;
|
|
3589
|
+
}
|
|
3590
|
+
}
|
|
3591
|
+
if (!resp.ok) {
|
|
3592
|
+
const code = raw && typeof raw === "object" && "code" in raw && typeof raw.code === "string" ? raw.code : `http_${resp.status}`;
|
|
3593
|
+
const message = raw && typeof raw === "object" && "message" in raw && typeof raw.message === "string" ? raw.message : `request failed with status ${resp.status}`;
|
|
3594
|
+
throw new FlurApiError(resp.status, code, message, raw);
|
|
3595
|
+
}
|
|
3596
|
+
return parser(raw);
|
|
3597
|
+
}
|
|
3598
|
+
return {
|
|
3599
|
+
listDestinations: () => call(
|
|
3600
|
+
"GET",
|
|
3601
|
+
"/v1/me/payout-destinations",
|
|
3602
|
+
void 0,
|
|
3603
|
+
(raw) => ListPayoutDestinationsResultSchema.parse(raw)
|
|
3604
|
+
),
|
|
3605
|
+
createDestination: (input) => call(
|
|
3606
|
+
"POST",
|
|
3607
|
+
"/v1/me/payout-destinations",
|
|
3608
|
+
CreatePayoutDestinationInputSchema.parse(input),
|
|
3609
|
+
(raw) => PayoutDestinationSchema.parse(raw)
|
|
3610
|
+
),
|
|
3611
|
+
verifyDestination: (destinationId) => call(
|
|
3612
|
+
"POST",
|
|
3613
|
+
`/v1/me/payout-destinations/${encodeURIComponent(destinationId)}/verify`,
|
|
3614
|
+
{},
|
|
3615
|
+
(raw) => PayoutDestinationSchema.parse(raw)
|
|
3616
|
+
),
|
|
3617
|
+
disableDestination: (destinationId) => call(
|
|
3618
|
+
"POST",
|
|
3619
|
+
`/v1/me/payout-destinations/${encodeURIComponent(destinationId)}/disable`,
|
|
3620
|
+
{},
|
|
3621
|
+
(raw) => PayoutDestinationSchema.parse(raw)
|
|
3622
|
+
),
|
|
3623
|
+
createWithdrawal: (input) => call(
|
|
3624
|
+
"POST",
|
|
3625
|
+
"/v1/me/withdrawals",
|
|
3626
|
+
CreateWithdrawalInputSchema.parse(input),
|
|
3627
|
+
(raw) => CreateWithdrawalResultSchema.parse(raw)
|
|
3628
|
+
),
|
|
3629
|
+
getWithdrawal: (withdrawalId) => call(
|
|
3630
|
+
"GET",
|
|
3631
|
+
`/v1/me/withdrawals/${encodeURIComponent(withdrawalId)}`,
|
|
3632
|
+
void 0,
|
|
3633
|
+
(raw) => WithdrawalSchema.parse(raw)
|
|
3634
|
+
)
|
|
3635
|
+
};
|
|
3636
|
+
}
|
|
3637
|
+
function createPartnerProfileAdminClient(opts) {
|
|
3638
|
+
const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
|
|
3639
|
+
if (!fetchImpl) {
|
|
3640
|
+
throw new Error(
|
|
3641
|
+
"createPartnerProfileAdminClient: no fetch implementation available"
|
|
3642
|
+
);
|
|
3643
|
+
}
|
|
3644
|
+
const baseUrl = opts.baseUrl.replace(/\/$/, "");
|
|
3645
|
+
return {
|
|
3646
|
+
upsertProfile: async (partnerAccountId, input) => {
|
|
3647
|
+
const body = {
|
|
3648
|
+
partnerAccountId,
|
|
3649
|
+
...UpsertPartnerProfileInputSchema.parse(input)
|
|
3650
|
+
};
|
|
3651
|
+
const resp = await fetchImpl(`${baseUrl}/v1/partners/profile`, {
|
|
3652
|
+
method: "POST",
|
|
3653
|
+
headers: {
|
|
3654
|
+
"content-type": "application/json",
|
|
3655
|
+
accept: "application/json"
|
|
3656
|
+
},
|
|
3657
|
+
body: JSON.stringify(body)
|
|
3658
|
+
});
|
|
3659
|
+
const text = await resp.text();
|
|
3660
|
+
let raw;
|
|
3661
|
+
if (text) {
|
|
3662
|
+
try {
|
|
3663
|
+
raw = JSON.parse(text);
|
|
3664
|
+
} catch {
|
|
3665
|
+
raw = text;
|
|
3666
|
+
}
|
|
3667
|
+
}
|
|
3668
|
+
if (!resp.ok) {
|
|
3669
|
+
const code = raw && typeof raw === "object" && "code" in raw && typeof raw.code === "string" ? raw.code : `http_${resp.status}`;
|
|
3670
|
+
const message = raw && typeof raw === "object" && "message" in raw && typeof raw.message === "string" ? raw.message : `request failed with status ${resp.status}`;
|
|
3671
|
+
throw new FlurApiError(resp.status, code, message, raw);
|
|
3672
|
+
}
|
|
3673
|
+
return PartnerProfileSchema.parse(raw);
|
|
3674
|
+
}
|
|
3675
|
+
};
|
|
3676
|
+
}
|
|
2946
3677
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2947
3678
|
0 && (module.exports = {
|
|
2948
3679
|
ACCOUNT_STATUSES,
|
|
@@ -2951,11 +3682,24 @@ function createMeOfflineClient(opts) {
|
|
|
2951
3682
|
AccountMembershipSchema,
|
|
2952
3683
|
AccountSchema,
|
|
2953
3684
|
ApiCredentialPublicSchema,
|
|
3685
|
+
COLLECTION_INTENT_STATUSES,
|
|
3686
|
+
COLLECTION_PAYMENT_STATUSES,
|
|
3687
|
+
CUSTODIAL_MODES,
|
|
3688
|
+
CollectionIntentSchema,
|
|
3689
|
+
CollectionPaymentResultSchema,
|
|
3690
|
+
CollectionPaymentSchema,
|
|
3691
|
+
CollectionReportSummarySchema,
|
|
3692
|
+
CollectionStatementSchema,
|
|
2954
3693
|
ConsumerOACRecordSchema,
|
|
2955
3694
|
ConsumerOACSchema,
|
|
2956
3695
|
ConsumerPaymentClaimSchema,
|
|
2957
3696
|
ConsumerSettleResultSchema,
|
|
2958
3697
|
ConsumerSettlementSchema,
|
|
3698
|
+
CreateCollectionIntentInputSchema,
|
|
3699
|
+
CreatePayoutDestinationInputSchema,
|
|
3700
|
+
CreatePayoutInputSchema,
|
|
3701
|
+
CreateWithdrawalInputSchema,
|
|
3702
|
+
CreateWithdrawalResultSchema,
|
|
2959
3703
|
DeviceKeyRecordSchema,
|
|
2960
3704
|
DisableOfflineInputSchema,
|
|
2961
3705
|
DisableOfflineResultSchema,
|
|
@@ -2968,8 +3712,14 @@ function createMeOfflineClient(opts) {
|
|
|
2968
3712
|
FlurError,
|
|
2969
3713
|
FlurExpiredError,
|
|
2970
3714
|
FlurReplayError,
|
|
3715
|
+
IngestFundingResultSchema,
|
|
2971
3716
|
IssueOACInputSchema,
|
|
3717
|
+
ListPayoutDestinationsResultSchema,
|
|
2972
3718
|
MEMBERSHIP_ROLES,
|
|
3719
|
+
MERCHANT_PAYOUT_STATUSES,
|
|
3720
|
+
MERCHANT_PROFILE_STATUSES,
|
|
3721
|
+
MerchantPayoutSchema,
|
|
3722
|
+
MerchantProfileSchema,
|
|
2973
3723
|
MintedApiCredentialSchema,
|
|
2974
3724
|
NGN_CURRENCY_CODE,
|
|
2975
3725
|
NG_COUNTRY_CODE,
|
|
@@ -2984,25 +3734,46 @@ function createMeOfflineClient(opts) {
|
|
|
2984
3734
|
OfflineStateResultSchema,
|
|
2985
3735
|
OfflineStatusResultSchema,
|
|
2986
3736
|
OfflineTokenSchema,
|
|
3737
|
+
PARTNER_FUNDING_DIRECTIONS,
|
|
3738
|
+
PARTNER_FUNDING_STATUSES,
|
|
3739
|
+
PARTNER_KINDS,
|
|
3740
|
+
PARTNER_PROFILE_STATUSES,
|
|
2987
3741
|
PARTNER_SCOPES,
|
|
2988
3742
|
PASS_KINDS,
|
|
2989
3743
|
PASS_STATES,
|
|
2990
3744
|
PAYLOAD_FORMAT_INDICATOR_VALUE,
|
|
3745
|
+
PAYOUT_DESTINATION_STATUSES,
|
|
2991
3746
|
POINT_OF_INITIATION,
|
|
3747
|
+
PartnerFundingEventInputSchema,
|
|
3748
|
+
PartnerFundingSchema,
|
|
3749
|
+
PartnerProfileSchema,
|
|
2992
3750
|
PassMetadataSchema,
|
|
2993
3751
|
PassSchema,
|
|
3752
|
+
PayCollectionInputSchema,
|
|
2994
3753
|
PaymentClaimSchema,
|
|
3754
|
+
PayoutDestinationSchema,
|
|
3755
|
+
PayoutEventInputSchema,
|
|
3756
|
+
ProviderEventInputSchema,
|
|
3757
|
+
ProviderEventRecordSchema,
|
|
3758
|
+
PublicCollectionIntentSchema,
|
|
2995
3759
|
RECEIPT_CHANNELS,
|
|
2996
3760
|
RECEIPT_KINDS,
|
|
2997
3761
|
REPLAY_WINDOW_MS,
|
|
2998
3762
|
ReceiptPayloadSchema,
|
|
2999
3763
|
ReceiptSchema,
|
|
3764
|
+
ReconciliationReportSchema,
|
|
3765
|
+
RecordPayoutEventResultSchema,
|
|
3000
3766
|
RedemptionSchema,
|
|
3001
3767
|
RegisterDeviceKeyInputSchema,
|
|
3002
3768
|
RevokeDeviceKeyInputSchema,
|
|
3769
|
+
SETTLEMENT_SCHEDULES,
|
|
3003
3770
|
SettleResponseSchema,
|
|
3004
3771
|
SettlementSchema,
|
|
3005
3772
|
SignedConsumerOACSchema,
|
|
3773
|
+
UpsertMerchantProfileInputSchema,
|
|
3774
|
+
UpsertPartnerProfileInputSchema,
|
|
3775
|
+
WITHDRAWAL_STATES,
|
|
3776
|
+
WithdrawalSchema,
|
|
3006
3777
|
bodySha256Hex,
|
|
3007
3778
|
buildAuthorization,
|
|
3008
3779
|
buildOAC,
|
|
@@ -3019,10 +3790,16 @@ function createMeOfflineClient(opts) {
|
|
|
3019
3790
|
crc16ccittHex,
|
|
3020
3791
|
createAccountsClient,
|
|
3021
3792
|
createApiCredentialsAdminClient,
|
|
3793
|
+
createCollectionsClient,
|
|
3794
|
+
createConsumerCollectionsClient,
|
|
3795
|
+
createConsumerWithdrawalsClient,
|
|
3022
3796
|
createFlurPartnerClient,
|
|
3023
3797
|
createHmacFetch,
|
|
3024
3798
|
createMeOfflineClient,
|
|
3025
3799
|
createOfflineSettlementsClient,
|
|
3800
|
+
createPartnerCollectionsClient,
|
|
3801
|
+
createPartnerFundingClient,
|
|
3802
|
+
createPartnerProfileAdminClient,
|
|
3026
3803
|
createPassesClient,
|
|
3027
3804
|
createReceiptsClient,
|
|
3028
3805
|
decodeAuthorizationQR,
|