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