@peable.to/contracts 0.4.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/common/address.js +81 -0
- package/dist/cjs/common/envelopes.js +101 -0
- package/dist/cjs/common/objects.js +85 -0
- package/dist/cjs/common/params.js +211 -0
- package/dist/cjs/common/primitives.js +39 -0
- package/dist/cjs/contributions.js +22 -0
- package/dist/cjs/index.js +40 -137
- package/dist/cjs/openapi/document.js +297 -0
- package/dist/cjs/openapi/index.js +7 -0
- package/dist/cjs/openapi/webhooks.js +17 -0
- package/dist/cjs/resources/billingEngine/billingPortal.js +237 -0
- package/dist/cjs/resources/billingEngine/creditNotes.js +189 -0
- package/dist/cjs/resources/billingEngine/customerBalanceTransactions.js +90 -0
- package/dist/cjs/resources/billingEngine/index.js +43 -0
- package/dist/cjs/resources/billingEngine/invoiceItems.js +155 -0
- package/dist/cjs/resources/billingEngine/invoices.js +509 -0
- package/dist/cjs/resources/billingEngine/params.js +43 -0
- package/dist/cjs/resources/billingEngine/public.js +326 -0
- package/dist/cjs/resources/billingEngine/subscriptions.js +476 -0
- package/dist/cjs/resources/catalog/billing.js +755 -0
- package/dist/cjs/resources/catalog/billingSettings.js +131 -0
- package/dist/cjs/resources/catalog/coupons.js +222 -0
- package/dist/cjs/resources/catalog/entitlements.js +257 -0
- package/dist/cjs/resources/catalog/index.js +58 -0
- package/dist/cjs/resources/catalog/meters.js +279 -0
- package/dist/cjs/resources/catalog/prices.js +423 -0
- package/dist/cjs/resources/catalog/products.js +228 -0
- package/dist/cjs/resources/catalog/promotionCodes.js +174 -0
- package/dist/cjs/resources/catalog/shared.js +75 -0
- package/dist/cjs/resources/catalog/testClocks.js +127 -0
- package/dist/cjs/resources/checkout/checkoutSessions.js +582 -0
- package/dist/cjs/resources/checkout/contributions.js +172 -0
- package/dist/cjs/resources/checkout/files.js +133 -0
- package/dist/cjs/resources/checkout/index.js +57 -0
- package/dist/cjs/resources/checkout/merchants.js +290 -0
- package/dist/cjs/resources/checkout/paymentLinks.js +330 -0
- package/dist/cjs/resources/checkout/paymentMethodConfigurations.js +262 -0
- package/dist/cjs/resources/checkout/shared.js +368 -0
- package/dist/cjs/resources/connect/account.js +332 -0
- package/dist/cjs/resources/connect/applicationFees.js +113 -0
- package/dist/cjs/resources/connect/balance.js +212 -0
- package/dist/cjs/resources/connect/connectedAccounts.js +260 -0
- package/dist/cjs/resources/connect/index.js +51 -0
- package/dist/cjs/resources/connect/onboarding.js +82 -0
- package/dist/cjs/resources/connect/payouts.js +196 -0
- package/dist/cjs/resources/connect/reporting.js +235 -0
- package/dist/cjs/resources/connect/requestLogs.js +110 -0
- package/dist/cjs/resources/connect/transfers.js +227 -0
- package/dist/cjs/resources/core/customers.js +194 -0
- package/dist/cjs/resources/core/index.js +23 -0
- package/dist/cjs/resources/core/paymentMethods.js +134 -0
- package/dist/cjs/resources/events/events.js +357 -0
- package/dist/cjs/resources/events/index.js +29 -0
- package/dist/cjs/resources/events/webhookDeliveries.js +93 -0
- package/dist/cjs/resources/events/webhookEndpoints.js +215 -0
- package/dist/cjs/resources/payments/charges.js +157 -0
- package/dist/cjs/resources/payments/disputes.js +204 -0
- package/dist/cjs/resources/payments/index.js +41 -0
- package/dist/cjs/resources/payments/paymentIntents.js +529 -0
- package/dist/cjs/resources/payments/refunds.js +245 -0
- package/dist/cjs/resources/payments/setupIntents.js +158 -0
- package/dist/cjs/resources/payments/social.js +182 -0
- package/dist/cjs/resources/payments/testHelpers.js +39 -0
- package/dist/cjs/resources/tax/assessments.js +217 -0
- package/dist/cjs/resources/tax/businessProfile.js +99 -0
- package/dist/cjs/resources/tax/calculations.js +176 -0
- package/dist/cjs/resources/tax/capabilities.js +42 -0
- package/dist/cjs/resources/tax/codes.js +37 -0
- package/dist/cjs/resources/tax/complianceActions.js +56 -0
- package/dist/cjs/resources/tax/deadlines.js +59 -0
- package/dist/cjs/resources/tax/documents.js +128 -0
- package/dist/cjs/resources/tax/index.js +80 -0
- package/dist/cjs/resources/tax/locationEvidence.js +131 -0
- package/dist/cjs/resources/tax/operatingLocations.js +98 -0
- package/dist/cjs/resources/tax/products.js +67 -0
- package/dist/cjs/resources/tax/registrationDeclarations.js +124 -0
- package/dist/cjs/resources/tax/registrations.js +82 -0
- package/dist/cjs/resources/tax/reports.js +92 -0
- package/dist/cjs/resources/tax/reviewItems.js +116 -0
- package/dist/cjs/resources/tax/ruleSet.js +68 -0
- package/dist/cjs/resources/tax/salesDestinations.js +94 -0
- package/dist/cjs/resources/tax/settings.js +104 -0
- package/dist/cjs/resources/tax/shared.js +62 -0
- package/dist/cjs/resources/tax/transactions.js +102 -0
- package/dist/cjs/route.js +22 -0
- package/dist/cjs/routes.js +31 -0
- package/dist/cjs/vocabulary/billingPortal.js +15 -0
- package/dist/cjs/vocabulary/catalog.js +110 -0
- package/dist/cjs/vocabulary/checkout.js +53 -0
- package/dist/cjs/vocabulary/connect.js +95 -0
- package/dist/cjs/vocabulary/errors.js +174 -0
- package/dist/cjs/vocabulary/events.js +176 -0
- package/dist/cjs/vocabulary/files.js +44 -0
- package/dist/cjs/vocabulary/index.js +37 -0
- package/dist/cjs/vocabulary/invoices.js +52 -0
- package/dist/cjs/vocabulary/lists.js +22 -0
- package/dist/cjs/vocabulary/merchants.js +23 -0
- package/dist/cjs/vocabulary/money.js +104 -0
- package/dist/cjs/vocabulary/paymentMethodConfigurations.js +36 -0
- package/dist/cjs/vocabulary/payments.js +195 -0
- package/dist/cjs/vocabulary/reporting.js +27 -0
- package/dist/cjs/vocabulary/subscriptions.js +60 -0
- package/dist/cjs/vocabulary/tax.js +237 -0
- package/dist/cjs/vocabulary/version.js +12 -0
- package/dist/esm/common/address.js +76 -0
- package/dist/esm/common/envelopes.js +95 -0
- package/dist/esm/common/objects.js +74 -0
- package/dist/esm/common/params.js +203 -0
- package/dist/esm/common/primitives.js +35 -0
- package/dist/esm/contributions.js +5 -0
- package/dist/esm/index.js +26 -134
- package/dist/esm/openapi/document.js +294 -0
- package/dist/esm/openapi/index.js +2 -0
- package/dist/esm/openapi/webhooks.js +14 -0
- package/dist/esm/resources/billingEngine/billingPortal.js +234 -0
- package/dist/esm/resources/billingEngine/creditNotes.js +186 -0
- package/dist/esm/resources/billingEngine/customerBalanceTransactions.js +87 -0
- package/dist/esm/resources/billingEngine/index.js +26 -0
- package/dist/esm/resources/billingEngine/invoiceItems.js +152 -0
- package/dist/esm/resources/billingEngine/invoices.js +506 -0
- package/dist/esm/resources/billingEngine/params.js +39 -0
- package/dist/esm/resources/billingEngine/public.js +323 -0
- package/dist/esm/resources/billingEngine/subscriptions.js +473 -0
- package/dist/esm/resources/catalog/billing.js +752 -0
- package/dist/esm/resources/catalog/billingSettings.js +128 -0
- package/dist/esm/resources/catalog/coupons.js +219 -0
- package/dist/esm/resources/catalog/entitlements.js +254 -0
- package/dist/esm/resources/catalog/index.js +38 -0
- package/dist/esm/resources/catalog/meters.js +276 -0
- package/dist/esm/resources/catalog/prices.js +419 -0
- package/dist/esm/resources/catalog/products.js +225 -0
- package/dist/esm/resources/catalog/promotionCodes.js +171 -0
- package/dist/esm/resources/catalog/shared.js +67 -0
- package/dist/esm/resources/catalog/testClocks.js +124 -0
- package/dist/esm/resources/checkout/checkoutSessions.js +579 -0
- package/dist/esm/resources/checkout/contributions.js +167 -0
- package/dist/esm/resources/checkout/files.js +130 -0
- package/dist/esm/resources/checkout/index.js +25 -0
- package/dist/esm/resources/checkout/merchants.js +287 -0
- package/dist/esm/resources/checkout/paymentLinks.js +327 -0
- package/dist/esm/resources/checkout/paymentMethodConfigurations.js +259 -0
- package/dist/esm/resources/checkout/shared.js +363 -0
- package/dist/esm/resources/connect/account.js +329 -0
- package/dist/esm/resources/connect/applicationFees.js +110 -0
- package/dist/esm/resources/connect/balance.js +209 -0
- package/dist/esm/resources/connect/connectedAccounts.js +257 -0
- package/dist/esm/resources/connect/index.js +34 -0
- package/dist/esm/resources/connect/onboarding.js +79 -0
- package/dist/esm/resources/connect/payouts.js +193 -0
- package/dist/esm/resources/connect/reporting.js +232 -0
- package/dist/esm/resources/connect/requestLogs.js +107 -0
- package/dist/esm/resources/connect/transfers.js +224 -0
- package/dist/esm/resources/core/customers.js +191 -0
- package/dist/esm/resources/core/index.js +6 -0
- package/dist/esm/resources/core/paymentMethods.js +131 -0
- package/dist/esm/resources/events/events.js +353 -0
- package/dist/esm/resources/events/index.js +12 -0
- package/dist/esm/resources/events/webhookDeliveries.js +90 -0
- package/dist/esm/resources/events/webhookEndpoints.js +212 -0
- package/dist/esm/resources/payments/charges.js +154 -0
- package/dist/esm/resources/payments/disputes.js +201 -0
- package/dist/esm/resources/payments/index.js +24 -0
- package/dist/esm/resources/payments/paymentIntents.js +526 -0
- package/dist/esm/resources/payments/refunds.js +242 -0
- package/dist/esm/resources/payments/setupIntents.js +155 -0
- package/dist/esm/resources/payments/social.js +179 -0
- package/dist/esm/resources/payments/testHelpers.js +36 -0
- package/dist/esm/resources/tax/assessments.js +214 -0
- package/dist/esm/resources/tax/businessProfile.js +96 -0
- package/dist/esm/resources/tax/calculations.js +173 -0
- package/dist/esm/resources/tax/capabilities.js +39 -0
- package/dist/esm/resources/tax/codes.js +34 -0
- package/dist/esm/resources/tax/complianceActions.js +53 -0
- package/dist/esm/resources/tax/deadlines.js +56 -0
- package/dist/esm/resources/tax/documents.js +125 -0
- package/dist/esm/resources/tax/index.js +63 -0
- package/dist/esm/resources/tax/locationEvidence.js +128 -0
- package/dist/esm/resources/tax/operatingLocations.js +95 -0
- package/dist/esm/resources/tax/products.js +64 -0
- package/dist/esm/resources/tax/registrationDeclarations.js +121 -0
- package/dist/esm/resources/tax/registrations.js +79 -0
- package/dist/esm/resources/tax/reports.js +89 -0
- package/dist/esm/resources/tax/reviewItems.js +113 -0
- package/dist/esm/resources/tax/ruleSet.js +65 -0
- package/dist/esm/resources/tax/salesDestinations.js +91 -0
- package/dist/esm/resources/tax/settings.js +101 -0
- package/dist/esm/resources/tax/shared.js +58 -0
- package/dist/esm/resources/tax/transactions.js +99 -0
- package/dist/esm/route.js +16 -0
- package/dist/esm/routes.js +27 -0
- package/dist/esm/vocabulary/billingPortal.js +12 -0
- package/dist/esm/vocabulary/catalog.js +106 -0
- package/dist/esm/vocabulary/checkout.js +50 -0
- package/dist/esm/vocabulary/connect.js +92 -0
- package/dist/esm/vocabulary/errors.js +169 -0
- package/dist/esm/vocabulary/events.js +173 -0
- package/dist/esm/vocabulary/files.js +41 -0
- package/dist/esm/vocabulary/index.js +21 -0
- package/dist/esm/vocabulary/invoices.js +49 -0
- package/dist/esm/vocabulary/lists.js +19 -0
- package/dist/esm/vocabulary/merchants.js +20 -0
- package/dist/esm/vocabulary/money.js +98 -0
- package/dist/esm/vocabulary/paymentMethodConfigurations.js +33 -0
- package/dist/esm/vocabulary/payments.js +192 -0
- package/dist/esm/vocabulary/reporting.js +24 -0
- package/dist/esm/vocabulary/subscriptions.js +57 -0
- package/dist/esm/vocabulary/tax.js +233 -0
- package/dist/esm/vocabulary/version.js +9 -0
- package/dist/types/common/address.d.ts +62 -0
- package/dist/types/common/envelopes.d.ts +88 -0
- package/dist/types/common/objects.d.ts +107 -0
- package/dist/types/common/params.d.ts +156 -0
- package/dist/types/common/primitives.d.ts +56 -0
- package/dist/types/contributions.d.ts +1 -0
- package/dist/types/index.d.ts +16 -171
- package/dist/types/openapi/document.d.ts +16 -0
- package/dist/types/openapi/index.d.ts +2 -0
- package/dist/types/openapi/webhooks.d.ts +15 -0
- package/dist/types/resources/billingEngine/billingPortal.d.ts +742 -0
- package/dist/types/resources/billingEngine/creditNotes.d.ts +655 -0
- package/dist/types/resources/billingEngine/customerBalanceTransactions.d.ts +282 -0
- package/dist/types/resources/billingEngine/index.d.ts +6071 -0
- package/dist/types/resources/billingEngine/invoiceItems.d.ts +502 -0
- package/dist/types/resources/billingEngine/invoices.d.ts +2547 -0
- package/dist/types/resources/billingEngine/params.d.ts +51 -0
- package/dist/types/resources/billingEngine/public.d.ts +1860 -0
- package/dist/types/resources/billingEngine/subscriptions.d.ts +1519 -0
- package/dist/types/resources/catalog/billing.d.ts +1723 -0
- package/dist/types/resources/catalog/billingSettings.d.ts +160 -0
- package/dist/types/resources/catalog/coupons.d.ts +403 -0
- package/dist/types/resources/catalog/entitlements.d.ts +422 -0
- package/dist/types/resources/catalog/index.d.ts +3155 -0
- package/dist/types/resources/catalog/meters.d.ts +474 -0
- package/dist/types/resources/catalog/prices.d.ts +1091 -0
- package/dist/types/resources/catalog/products.d.ts +430 -0
- package/dist/types/resources/catalog/promotionCodes.d.ts +369 -0
- package/dist/types/resources/catalog/shared.d.ts +34 -0
- package/dist/types/resources/catalog/testClocks.d.ts +220 -0
- package/dist/types/resources/checkout/checkoutSessions.d.ts +3207 -0
- package/dist/types/resources/checkout/contributions.d.ts +375 -0
- package/dist/types/resources/checkout/files.d.ts +280 -0
- package/dist/types/resources/checkout/index.d.ts +5678 -0
- package/dist/types/resources/checkout/merchants.d.ts +395 -0
- package/dist/types/resources/checkout/paymentLinks.d.ts +1728 -0
- package/dist/types/resources/checkout/paymentMethodConfigurations.d.ts +2104 -0
- package/dist/types/resources/checkout/shared.d.ts +419 -0
- package/dist/types/resources/connect/account.d.ts +483 -0
- package/dist/types/resources/connect/applicationFees.d.ts +198 -0
- package/dist/types/resources/connect/balance.d.ts +399 -0
- package/dist/types/resources/connect/connectedAccounts.d.ts +494 -0
- package/dist/types/resources/connect/index.d.ts +2094 -0
- package/dist/types/resources/connect/onboarding.d.ts +95 -0
- package/dist/types/resources/connect/payouts.d.ts +527 -0
- package/dist/types/resources/connect/reporting.d.ts +506 -0
- package/dist/types/resources/connect/requestLogs.d.ts +236 -0
- package/dist/types/resources/connect/transfers.d.ts +436 -0
- package/dist/types/resources/core/customers.d.ts +619 -0
- package/dist/types/resources/core/index.d.ts +679 -0
- package/dist/types/resources/core/paymentMethods.d.ts +336 -0
- package/dist/types/resources/events/events.d.ts +731 -0
- package/dist/types/resources/events/index.d.ts +1727 -0
- package/dist/types/resources/events/webhookDeliveries.d.ts +436 -0
- package/dist/types/resources/events/webhookEndpoints.d.ts +1502 -0
- package/dist/types/resources/payments/charges.d.ts +390 -0
- package/dist/types/resources/payments/disputes.d.ts +822 -0
- package/dist/types/resources/payments/index.d.ts +3517 -0
- package/dist/types/resources/payments/paymentIntents.d.ts +2080 -0
- package/dist/types/resources/payments/refunds.d.ts +684 -0
- package/dist/types/resources/payments/setupIntents.d.ts +391 -0
- package/dist/types/resources/payments/social.d.ts +266 -0
- package/dist/types/resources/payments/testHelpers.d.ts +178 -0
- package/dist/types/resources/tax/assessments.d.ts +787 -0
- package/dist/types/resources/tax/businessProfile.d.ts +134 -0
- package/dist/types/resources/tax/calculations.d.ts +261 -0
- package/dist/types/resources/tax/capabilities.d.ts +81 -0
- package/dist/types/resources/tax/codes.d.ts +29 -0
- package/dist/types/resources/tax/complianceActions.d.ts +97 -0
- package/dist/types/resources/tax/deadlines.d.ts +133 -0
- package/dist/types/resources/tax/documents.d.ts +257 -0
- package/dist/types/resources/tax/index.d.ts +1946 -0
- package/dist/types/resources/tax/locationEvidence.d.ts +246 -0
- package/dist/types/resources/tax/operatingLocations.d.ts +170 -0
- package/dist/types/resources/tax/products.d.ts +68 -0
- package/dist/types/resources/tax/registrationDeclarations.d.ts +270 -0
- package/dist/types/resources/tax/registrations.d.ts +103 -0
- package/dist/types/resources/tax/reports.d.ts +129 -0
- package/dist/types/resources/tax/reviewItems.d.ts +226 -0
- package/dist/types/resources/tax/ruleSet.d.ts +219 -0
- package/dist/types/resources/tax/salesDestinations.d.ts +158 -0
- package/dist/types/resources/tax/settings.d.ts +122 -0
- package/dist/types/resources/tax/shared.d.ts +43 -0
- package/dist/types/resources/tax/transactions.d.ts +404 -0
- package/dist/types/route.d.ts +86 -0
- package/dist/types/routes.d.ts +23 -0
- package/dist/types/vocabulary/billingPortal.d.ts +15 -0
- package/dist/types/vocabulary/catalog.d.ts +97 -0
- package/dist/types/vocabulary/checkout.d.ts +49 -0
- package/dist/types/vocabulary/connect.d.ts +62 -0
- package/dist/types/vocabulary/errors.d.ts +145 -0
- package/dist/types/vocabulary/events.d.ts +171 -0
- package/dist/types/vocabulary/files.d.ts +30 -0
- package/dist/types/vocabulary/index.d.ts +17 -0
- package/dist/types/vocabulary/invoices.d.ts +39 -0
- package/dist/types/vocabulary/lists.d.ts +9 -0
- package/dist/types/vocabulary/merchants.d.ts +9 -0
- package/dist/types/vocabulary/money.d.ts +59 -0
- package/dist/types/vocabulary/paymentMethodConfigurations.d.ts +22 -0
- package/dist/types/vocabulary/payments.d.ts +117 -0
- package/dist/types/vocabulary/reporting.d.ts +18 -0
- package/dist/types/vocabulary/subscriptions.d.ts +45 -0
- package/dist/types/vocabulary/tax.d.ts +163 -0
- package/dist/types/vocabulary/version.d.ts +10 -0
- package/package.json +51 -11
- package/dist/cjs/openapi.js +0 -165
- package/dist/esm/openapi.js +0 -161
- package/dist/types/openapi.d.ts +0 -148
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { listOf, searchResultOf } from '../../common/envelopes.js';
|
|
3
|
+
import { defineObject, expandable } from '../../common/objects.js';
|
|
4
|
+
import { expandOnlyQuery, idParam, listQuery, metadataCreateParam, metadataUpdateParam, searchQuery, } from '../../common/params.js';
|
|
5
|
+
import { amount, currency, livemode, metadata, nullableString, signedAmount, unixSeconds, } from '../../common/primitives.js';
|
|
6
|
+
import { defineRoute } from '../../route.js';
|
|
7
|
+
import { isBaseUnitString } from '../../vocabulary/money.js';
|
|
8
|
+
import { REFUND_ORIGINS, REFUND_REASONS, REFUND_STATUSES, SETTLEMENT_STATUSES, } from '../../vocabulary/payments.js';
|
|
9
|
+
/**
|
|
10
|
+
* Refunds (`re_…`) and a payment's settlement figures. The provider's own
|
|
11
|
+
* refund id never appears: a merchant integrates against Peable and never
|
|
12
|
+
* learns which acquirer sat behind it (ADR 0001 D3).
|
|
13
|
+
*/
|
|
14
|
+
export const refundSchema = defineObject('refund', 'Refund', z
|
|
15
|
+
.object({
|
|
16
|
+
id: z.string(),
|
|
17
|
+
object: z.literal('refund'),
|
|
18
|
+
livemode,
|
|
19
|
+
external_ref: nullableString.describe("YOUR id for this refund (its idempotency); `null` on a refund imported from the provider (`origin: 'provider'`)."),
|
|
20
|
+
origin: z
|
|
21
|
+
.enum(REFUND_ORIGINS)
|
|
22
|
+
.describe('`provider`: it appeared at the acquirer (a dashboard refund, a dispute resolved) and was imported.'),
|
|
23
|
+
payment_intent: expandable('payment_intent', 'The refunded payment (`pi_…`), or the PaymentIntent with `expand[]=payment_intent`.'),
|
|
24
|
+
amount,
|
|
25
|
+
currency,
|
|
26
|
+
status: z
|
|
27
|
+
.enum(REFUND_STATUSES)
|
|
28
|
+
.describe("The MONEY's own lifecycle: a bank can reject a refund days later (`failed`); `canceled` only through `POST /v1/refunds/{id}/cancel`."),
|
|
29
|
+
reason: z.enum(REFUND_REASONS).nullable(),
|
|
30
|
+
failure_code: nullableString.describe("The provider's machine-readable reason, when it failed."),
|
|
31
|
+
metadata,
|
|
32
|
+
created: unixSeconds,
|
|
33
|
+
updated_at: unixSeconds,
|
|
34
|
+
})
|
|
35
|
+
.strict(), {
|
|
36
|
+
examples: [
|
|
37
|
+
{
|
|
38
|
+
id: 're_0193b8f2c1a87d3e9f4a',
|
|
39
|
+
object: 'refund',
|
|
40
|
+
livemode: false,
|
|
41
|
+
external_ref: 'order_6735_refund_1',
|
|
42
|
+
origin: 'merchant',
|
|
43
|
+
payment_intent: 'pi_0193b8f2c1a87d3e9f4a',
|
|
44
|
+
amount: '1000',
|
|
45
|
+
currency: 'EUR',
|
|
46
|
+
status: 'succeeded',
|
|
47
|
+
reason: 'requested_by_customer',
|
|
48
|
+
failure_code: null,
|
|
49
|
+
metadata: {},
|
|
50
|
+
created: 1793750400,
|
|
51
|
+
updated_at: 1793750460,
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
});
|
|
55
|
+
/**
|
|
56
|
+
* What a payment actually came to, as the PROVIDER reports it. Every figure is
|
|
57
|
+
* nullable and that is the contract: "the fee was zero" and "the fee is not
|
|
58
|
+
* known yet" are different facts, and `status` says which produced the nulls.
|
|
59
|
+
* It reports what the provider took; it attributes that cost to nobody.
|
|
60
|
+
*/
|
|
61
|
+
export const settlementSchema = defineObject('settlement', 'Settlement', z
|
|
62
|
+
.object({
|
|
63
|
+
object: z.literal('settlement'),
|
|
64
|
+
livemode,
|
|
65
|
+
payment_intent: expandable('payment_intent', 'The `pi_…` this describes, or the PaymentIntent with `expand[]=payment_intent`.'),
|
|
66
|
+
status: z
|
|
67
|
+
.enum(SETTLEMENT_STATUSES)
|
|
68
|
+
.describe('`available`: settled, the figures are final; `pending`: not final yet; `unknown`: there is none to read — **not zero**.'),
|
|
69
|
+
gross: amount.nullable().describe('Base units of `currency`.'),
|
|
70
|
+
fee: amount.nullable(),
|
|
71
|
+
net: signedAmount.nullable(),
|
|
72
|
+
currency: nullableString.describe("The SETTLEMENT currency (uppercase ISO 4217), which may differ from the payment's."),
|
|
73
|
+
available_on: unixSeconds.nullable().describe('When the funds become available.'),
|
|
74
|
+
exchange_rate: z
|
|
75
|
+
.number()
|
|
76
|
+
.nullable()
|
|
77
|
+
.describe('Present only when a conversion happened. `null` is not a rate of 1.'),
|
|
78
|
+
})
|
|
79
|
+
.strict());
|
|
80
|
+
export const createRefundParams = z
|
|
81
|
+
.object({
|
|
82
|
+
payment_intent: z.string().min(1).describe('The `pi_…` being refunded.'),
|
|
83
|
+
external_ref: z
|
|
84
|
+
.string()
|
|
85
|
+
.min(1)
|
|
86
|
+
.max(255)
|
|
87
|
+
.describe('YOUR id for this refund. The idempotency: the same ref answers the same refund.'),
|
|
88
|
+
// A zero refund is refused separately: `'0'` is a canonical integer string,
|
|
89
|
+
// and a zero refund would consume the merchant's `external_ref` so the REAL
|
|
90
|
+
// refund for that order could never be created afterwards.
|
|
91
|
+
amount: z
|
|
92
|
+
.string()
|
|
93
|
+
.refine(isBaseUnitString, 'amount must be a canonical integer string in minor units')
|
|
94
|
+
.refine((value) => value !== '0', 'a refund of 0 is not a refund')
|
|
95
|
+
.describe('Base units, as a canonical integer string. Zero is refused.'),
|
|
96
|
+
reason: z.enum(REFUND_REASONS).optional(),
|
|
97
|
+
metadata: metadataCreateParam.optional(),
|
|
98
|
+
refund_application_fee: z
|
|
99
|
+
.boolean()
|
|
100
|
+
.optional()
|
|
101
|
+
.describe("Also refund Orbit's application fee, in proportion (a destination charge)."),
|
|
102
|
+
reverse_transfer: z
|
|
103
|
+
.boolean()
|
|
104
|
+
.optional()
|
|
105
|
+
.describe('Also reverse the transfer to the destination account, in proportion.'),
|
|
106
|
+
})
|
|
107
|
+
.strict();
|
|
108
|
+
/** The merchant's own bookkeeping on a refund: `metadata`, a patch. */
|
|
109
|
+
export const updateRefundParams = z.object({ metadata: metadataUpdateParam.optional() }).strict();
|
|
110
|
+
export const cancelRefundParams = z.object({}).strict();
|
|
111
|
+
export const listRefundsQuery = listQuery({
|
|
112
|
+
payment_intent: idParam.optional().describe("Only this payment's refunds (`pi_…`)."),
|
|
113
|
+
});
|
|
114
|
+
/** The per-payment sub-list: the payment is in the path. */
|
|
115
|
+
export const listPaymentIntentRefundsQuery = listQuery({});
|
|
116
|
+
/**
|
|
117
|
+
* A payment's refunds, with what is still refundable beside the envelope — the
|
|
118
|
+
* figure every merchant would otherwise compute by summing the list, and get
|
|
119
|
+
* wrong by counting a `pending` or `failed` refund.
|
|
120
|
+
*/
|
|
121
|
+
export const paymentIntentRefundListSchema = listOf(refundSchema).extend({
|
|
122
|
+
remaining_refundable: amount.describe('What can still be refunded on this payment, in base units. The same on every page.'),
|
|
123
|
+
});
|
|
124
|
+
const refundId = { id: 'The refund (`re_…`).' };
|
|
125
|
+
const intentId = { intentId: 'The payment intent (`pi_…`).' };
|
|
126
|
+
export const refundRoutes = [
|
|
127
|
+
defineRoute({
|
|
128
|
+
operationId: 'createRefund',
|
|
129
|
+
method: 'post',
|
|
130
|
+
path: '/v1/refunds',
|
|
131
|
+
tag: 'Refunds',
|
|
132
|
+
summary: 'Create a refund',
|
|
133
|
+
description: '`external_ref` decides whether money moves twice: a retry with the same ref answers the refund it made (200) whatever is still refundable.',
|
|
134
|
+
auth: 'service',
|
|
135
|
+
scope: 'payments:write',
|
|
136
|
+
idempotent: true,
|
|
137
|
+
body: createRefundParams,
|
|
138
|
+
response: refundSchema,
|
|
139
|
+
status: 201,
|
|
140
|
+
sdk: 'refunds.create',
|
|
141
|
+
}),
|
|
142
|
+
defineRoute({
|
|
143
|
+
operationId: 'listRefunds',
|
|
144
|
+
method: 'get',
|
|
145
|
+
path: '/v1/refunds',
|
|
146
|
+
tag: 'Refunds',
|
|
147
|
+
summary: 'List refunds',
|
|
148
|
+
description: "Every refund of the merchant, or of one payment — including those made outside Peable (`origin: 'provider'`).",
|
|
149
|
+
auth: 'service',
|
|
150
|
+
scope: 'payments:read',
|
|
151
|
+
query: listRefundsQuery,
|
|
152
|
+
response: listOf(refundSchema),
|
|
153
|
+
sdk: 'refunds.list',
|
|
154
|
+
expandable: 'refund',
|
|
155
|
+
}),
|
|
156
|
+
defineRoute({
|
|
157
|
+
operationId: 'retrieveRefund',
|
|
158
|
+
method: 'get',
|
|
159
|
+
path: '/v1/refunds/{id}',
|
|
160
|
+
tag: 'Refunds',
|
|
161
|
+
summary: 'Retrieve a refund',
|
|
162
|
+
auth: 'service',
|
|
163
|
+
scope: 'payments:read',
|
|
164
|
+
params: refundId,
|
|
165
|
+
query: expandOnlyQuery,
|
|
166
|
+
response: refundSchema,
|
|
167
|
+
sdk: 'refunds.retrieve',
|
|
168
|
+
expandable: 'refund',
|
|
169
|
+
}),
|
|
170
|
+
defineRoute({
|
|
171
|
+
operationId: 'updateRefund',
|
|
172
|
+
method: 'post',
|
|
173
|
+
path: '/v1/refunds/{id}',
|
|
174
|
+
tag: 'Refunds',
|
|
175
|
+
summary: 'Update a refund',
|
|
176
|
+
auth: 'service',
|
|
177
|
+
scope: 'payments:write',
|
|
178
|
+
idempotent: true,
|
|
179
|
+
params: refundId,
|
|
180
|
+
body: updateRefundParams,
|
|
181
|
+
response: refundSchema,
|
|
182
|
+
sdk: 'refunds.update',
|
|
183
|
+
}),
|
|
184
|
+
defineRoute({
|
|
185
|
+
operationId: 'cancelRefund',
|
|
186
|
+
method: 'post',
|
|
187
|
+
path: '/v1/refunds/{id}/cancel',
|
|
188
|
+
tag: 'Refunds',
|
|
189
|
+
summary: 'Cancel a refund',
|
|
190
|
+
description: 'Only while the provider still holds it; otherwise 400 `refund_not_cancelable`.',
|
|
191
|
+
auth: 'service',
|
|
192
|
+
scope: 'payments:write',
|
|
193
|
+
idempotent: true,
|
|
194
|
+
params: refundId,
|
|
195
|
+
body: cancelRefundParams,
|
|
196
|
+
response: refundSchema,
|
|
197
|
+
sdk: 'refunds.cancel',
|
|
198
|
+
}),
|
|
199
|
+
defineRoute({
|
|
200
|
+
operationId: 'listPaymentIntentRefunds',
|
|
201
|
+
method: 'get',
|
|
202
|
+
path: '/v1/payment_intents/{intentId}/refunds',
|
|
203
|
+
tag: 'Refunds',
|
|
204
|
+
summary: "List a payment's refunds",
|
|
205
|
+
auth: 'service',
|
|
206
|
+
scope: 'payments:read',
|
|
207
|
+
params: intentId,
|
|
208
|
+
query: listPaymentIntentRefundsQuery,
|
|
209
|
+
response: paymentIntentRefundListSchema,
|
|
210
|
+
sdk: 'refunds.listForPaymentIntent',
|
|
211
|
+
expandable: 'refund',
|
|
212
|
+
}),
|
|
213
|
+
defineRoute({
|
|
214
|
+
operationId: 'retrievePaymentIntentSettlement',
|
|
215
|
+
method: 'get',
|
|
216
|
+
path: '/v1/payment_intents/{intentId}/settlement',
|
|
217
|
+
tag: 'Refunds',
|
|
218
|
+
summary: "Retrieve a payment's settlement",
|
|
219
|
+
description: 'Gross, fee and net, read live from the provider. A missing figure is `null` with a `status`, never `0`.',
|
|
220
|
+
auth: 'service',
|
|
221
|
+
scope: 'payments:read',
|
|
222
|
+
params: intentId,
|
|
223
|
+
query: expandOnlyQuery,
|
|
224
|
+
response: settlementSchema,
|
|
225
|
+
sdk: 'refunds.settlement',
|
|
226
|
+
expandable: 'settlement',
|
|
227
|
+
}),
|
|
228
|
+
defineRoute({
|
|
229
|
+
operationId: 'searchRefunds',
|
|
230
|
+
method: 'get',
|
|
231
|
+
path: '/v1/refunds/search',
|
|
232
|
+
tag: 'Refunds',
|
|
233
|
+
summary: 'Search refunds',
|
|
234
|
+
description: "Stripe's query language over `amount`, `currency`, `status`, `reason`, `payment_intent`, `created` and `metadata['key']`.",
|
|
235
|
+
auth: 'service',
|
|
236
|
+
scope: 'payments:read',
|
|
237
|
+
query: searchQuery,
|
|
238
|
+
response: searchResultOf(refundSchema),
|
|
239
|
+
sdk: 'refunds.search',
|
|
240
|
+
expandable: 'refund',
|
|
241
|
+
}),
|
|
242
|
+
];
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { listOf } from '../../common/envelopes.js';
|
|
3
|
+
import { defineObject, expandable } from '../../common/objects.js';
|
|
4
|
+
import { expandParam, idParam, listQuery, metadataCreateParam, retrieveQuery, } from '../../common/params.js';
|
|
5
|
+
import { livemode, metadata, nullableString, unixSeconds } from '../../common/primitives.js';
|
|
6
|
+
import { defineRoute } from '../../route.js';
|
|
7
|
+
import { SETUP_INTENT_CANCELLATION_REASONS, SETUP_INTENT_STATUSES, SETUP_INTENT_USAGES, } from '../../vocabulary/payments.js';
|
|
8
|
+
import { clientActionSchema, clientSecretParam, clientSecretQuery, paymentErrorSchema, } from './paymentIntents.js';
|
|
9
|
+
/**
|
|
10
|
+
* SetupIntents (`seti_…`) — saving a card for later without charging it
|
|
11
|
+
* (ADR 0016, ADR 0019). The provider SetupIntent is an internal binding; its
|
|
12
|
+
* success is what creates the Peable `pm_…`, attached to the customer.
|
|
13
|
+
*/
|
|
14
|
+
export const setupIntentSchema = defineObject('setup_intent', 'SetupIntent', z
|
|
15
|
+
.object({
|
|
16
|
+
id: z.string(),
|
|
17
|
+
object: z.literal('setup_intent'),
|
|
18
|
+
livemode,
|
|
19
|
+
status: z.enum(SETUP_INTENT_STATUSES),
|
|
20
|
+
usage: z.enum(SETUP_INTENT_USAGES),
|
|
21
|
+
payment_method_types: z.tuple([z.literal('card')]),
|
|
22
|
+
customer: expandable('customer', '`cus_…`, or the Customer with `expand[]=customer`.').nullable(),
|
|
23
|
+
payment_method: expandable('payment_method', 'The `pm_…` it saved, once `succeeded`, or the PaymentMethod with `expand[]=payment_method`.').nullable(),
|
|
24
|
+
client_secret: z
|
|
25
|
+
.string()
|
|
26
|
+
.describe("Possession of it lets the payer's browser confirm this SetupIntent."),
|
|
27
|
+
next_action: z
|
|
28
|
+
.object({ type: z.literal('use_peable_sdk') })
|
|
29
|
+
.strict()
|
|
30
|
+
.nullable(),
|
|
31
|
+
last_setup_error: paymentErrorSchema.nullable(),
|
|
32
|
+
cancellation_reason: z.enum(SETUP_INTENT_CANCELLATION_REASONS).nullable(),
|
|
33
|
+
description: nullableString,
|
|
34
|
+
metadata,
|
|
35
|
+
created: unixSeconds,
|
|
36
|
+
})
|
|
37
|
+
.strict(), {
|
|
38
|
+
examples: [
|
|
39
|
+
{
|
|
40
|
+
id: 'seti_0193b8f2c1a87d3e9f4a',
|
|
41
|
+
object: 'setup_intent',
|
|
42
|
+
livemode: false,
|
|
43
|
+
status: 'requires_payment_method',
|
|
44
|
+
usage: 'off_session',
|
|
45
|
+
payment_method_types: ['card'],
|
|
46
|
+
customer: 'cus_0193b8f2c1a87d3e9f4a',
|
|
47
|
+
payment_method: null,
|
|
48
|
+
client_secret: 'seti_0193b8f2c1a87d3e9f4a_secret_9a1b2c',
|
|
49
|
+
next_action: null,
|
|
50
|
+
last_setup_error: null,
|
|
51
|
+
cancellation_reason: null,
|
|
52
|
+
description: null,
|
|
53
|
+
metadata: {},
|
|
54
|
+
created: 1793750400,
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
});
|
|
58
|
+
export const createSetupIntentParams = z
|
|
59
|
+
.object({
|
|
60
|
+
customer: idParam
|
|
61
|
+
.optional()
|
|
62
|
+
.describe('The customer (`cus_…`) the card is saved to. Required: a `pm_…` is born attached.'),
|
|
63
|
+
usage: z.enum(SETUP_INTENT_USAGES).optional().describe('Defaults to `off_session`.'),
|
|
64
|
+
payment_method_types: z.tuple([z.literal('card')]).optional(),
|
|
65
|
+
description: z.string().max(1000).optional(),
|
|
66
|
+
metadata: metadataCreateParam.optional(),
|
|
67
|
+
expand: expandParam.optional(),
|
|
68
|
+
})
|
|
69
|
+
.strict();
|
|
70
|
+
export const cancelSetupIntentParams = z
|
|
71
|
+
.object({
|
|
72
|
+
cancellation_reason: z.enum(SETUP_INTENT_CANCELLATION_REASONS).optional(),
|
|
73
|
+
expand: expandParam.optional(),
|
|
74
|
+
})
|
|
75
|
+
.strict();
|
|
76
|
+
export const listSetupIntentsQuery = listQuery({
|
|
77
|
+
customer: idParam.optional().describe("Only this customer's setup intents (`cus_…`)."),
|
|
78
|
+
});
|
|
79
|
+
/** A merchant retrieve takes `expand[]`; the payer's takes `client_secret` and nothing to expand. */
|
|
80
|
+
export const retrieveSetupIntentQuery = retrieveQuery({ client_secret: clientSecretParam });
|
|
81
|
+
const setupIntentId = { id: 'The setup intent (`seti_…`).' };
|
|
82
|
+
export const setupIntentRoutes = [
|
|
83
|
+
defineRoute({
|
|
84
|
+
operationId: 'createSetupIntent',
|
|
85
|
+
method: 'post',
|
|
86
|
+
path: '/v1/setup_intents',
|
|
87
|
+
tag: 'Setup intents',
|
|
88
|
+
summary: 'Create a setup intent',
|
|
89
|
+
auth: 'service',
|
|
90
|
+
scope: 'payments:write',
|
|
91
|
+
idempotent: true,
|
|
92
|
+
body: createSetupIntentParams,
|
|
93
|
+
response: setupIntentSchema,
|
|
94
|
+
status: 201,
|
|
95
|
+
sdk: 'setupIntents.create',
|
|
96
|
+
expandable: 'setup_intent',
|
|
97
|
+
}),
|
|
98
|
+
defineRoute({
|
|
99
|
+
operationId: 'listSetupIntents',
|
|
100
|
+
method: 'get',
|
|
101
|
+
path: '/v1/setup_intents',
|
|
102
|
+
tag: 'Setup intents',
|
|
103
|
+
summary: 'List setup intents',
|
|
104
|
+
auth: 'service',
|
|
105
|
+
scope: 'payments:read',
|
|
106
|
+
query: listSetupIntentsQuery,
|
|
107
|
+
response: listOf(setupIntentSchema),
|
|
108
|
+
sdk: 'setupIntents.list',
|
|
109
|
+
expandable: 'setup_intent',
|
|
110
|
+
}),
|
|
111
|
+
defineRoute({
|
|
112
|
+
operationId: 'retrieveSetupIntent',
|
|
113
|
+
method: 'get',
|
|
114
|
+
path: '/v1/setup_intents/{id}',
|
|
115
|
+
tag: 'Setup intents',
|
|
116
|
+
summary: 'Retrieve a setup intent',
|
|
117
|
+
description: 'With the merchant credential: reconciled with the provider when not terminal, expandable. Without one, the PAYER reads the row as stored with its `client_secret` (the `X-Peable-Client-Secret` header, or the query).',
|
|
118
|
+
auth: 'service',
|
|
119
|
+
scope: 'payments:read',
|
|
120
|
+
params: setupIntentId,
|
|
121
|
+
query: retrieveSetupIntentQuery,
|
|
122
|
+
response: setupIntentSchema,
|
|
123
|
+
sdk: 'setupIntents.retrieve',
|
|
124
|
+
expandable: 'setup_intent',
|
|
125
|
+
}),
|
|
126
|
+
defineRoute({
|
|
127
|
+
operationId: 'cancelSetupIntent',
|
|
128
|
+
method: 'post',
|
|
129
|
+
path: '/v1/setup_intents/{id}/cancel',
|
|
130
|
+
tag: 'Setup intents',
|
|
131
|
+
summary: 'Cancel a setup intent',
|
|
132
|
+
auth: 'service',
|
|
133
|
+
scope: 'payments:write',
|
|
134
|
+
idempotent: true,
|
|
135
|
+
params: setupIntentId,
|
|
136
|
+
body: cancelSetupIntentParams,
|
|
137
|
+
response: setupIntentSchema,
|
|
138
|
+
sdk: 'setupIntents.cancel',
|
|
139
|
+
expandable: 'setup_intent',
|
|
140
|
+
}),
|
|
141
|
+
defineRoute({
|
|
142
|
+
operationId: 'retrieveSetupIntentClientAction',
|
|
143
|
+
method: 'post',
|
|
144
|
+
path: '/v1/setup_intents/{id}/client_action',
|
|
145
|
+
tag: 'Setup intents',
|
|
146
|
+
summary: "Retrieve a setup intent's client action",
|
|
147
|
+
description: "The provider credential the payer's client confirms the SetupIntent with — read fresh, `Cache-Control: no-store`, never on the object. The merchant credential, or the payer's `client_secret` (`X-Peable-Client-Secret`). A succeeded or canceled setup intent answers 409.",
|
|
148
|
+
auth: 'service',
|
|
149
|
+
scope: 'payments:read',
|
|
150
|
+
params: setupIntentId,
|
|
151
|
+
query: clientSecretQuery,
|
|
152
|
+
response: clientActionSchema,
|
|
153
|
+
sdk: 'setupIntents.clientAction',
|
|
154
|
+
}),
|
|
155
|
+
];
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { defineComponent } from '../../common/objects.js';
|
|
3
|
+
import { network, unixSeconds } from '../../common/primitives.js';
|
|
4
|
+
import { defineRoute } from '../../route.js';
|
|
5
|
+
import { ENRICH_MAX_ADDRESSES, ENRICHMENT_KINDS, SOCIAL_PAYMENT_DIRECTIONS, SOCIAL_SOURCE_APP_MAX_LENGTH, SOCIAL_SOURCE_REF_MAX_LENGTH, } from '../../vocabulary/payments.js';
|
|
6
|
+
/**
|
|
7
|
+
* Social payments (pay a person by `@username`) and transaction enrichment —
|
|
8
|
+
* the wallet's routes, called with the person's own Oxy session. Display-only
|
|
9
|
+
* context throughout: nothing here decides where money goes; the address comes
|
|
10
|
+
* from the recipient's identity key and their reservation cursor.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Display-only context for one social payment: which app the payer was in, and
|
|
14
|
+
* that app's own opaque id for what it was for (a Mention post, say). Peable
|
|
15
|
+
* never parses, resolves or links `ref`; it stores a string and hands the same
|
|
16
|
+
* string back.
|
|
17
|
+
*/
|
|
18
|
+
export const socialPaymentSourceSchema = defineComponent('SocialPaymentSource', z
|
|
19
|
+
.object({
|
|
20
|
+
app: z.string().describe("The calling app's slug, e.g. `mention`."),
|
|
21
|
+
ref: z
|
|
22
|
+
.string()
|
|
23
|
+
.optional()
|
|
24
|
+
.describe("That app's own opaque id for what the payment was for; absent when it named none."),
|
|
25
|
+
})
|
|
26
|
+
.strict());
|
|
27
|
+
/**
|
|
28
|
+
* Display-only counterparty identity for one address, as `POST /v1/enrich`
|
|
29
|
+
* resolves it. A failed or partial resolution degrades to `{ kind: 'unknown' }`.
|
|
30
|
+
*/
|
|
31
|
+
export const enrichmentResultSchema = defineComponent('EnrichmentResult', z
|
|
32
|
+
.object({
|
|
33
|
+
kind: z.enum(ENRICHMENT_KINDS),
|
|
34
|
+
display_name: z
|
|
35
|
+
.string()
|
|
36
|
+
.optional()
|
|
37
|
+
.describe("The merchant's name, or the user's display name (else handle)."),
|
|
38
|
+
avatar_file_id: z
|
|
39
|
+
.string()
|
|
40
|
+
.optional()
|
|
41
|
+
.describe('A bare Oxy file id — render through the media chokepoint, never as a URL.'),
|
|
42
|
+
username: z.string().optional().describe("`kind: 'user'` only."),
|
|
43
|
+
description: z.string().optional().describe("`kind: 'merchant'` only."),
|
|
44
|
+
})
|
|
45
|
+
.strict());
|
|
46
|
+
/**
|
|
47
|
+
* `.strict()` is load-bearing: `{ app, postId }` — the obvious misspelling of
|
|
48
|
+
* `ref` — would otherwise reserve an address and record a context missing the
|
|
49
|
+
* only part the recipient cares about, with a 200. `ref` is validated for SHAPE
|
|
50
|
+
* (printable non-space ASCII) and never for meaning, so it cannot become a
|
|
51
|
+
* free-text memo the gateway stores on behalf of two users.
|
|
52
|
+
*/
|
|
53
|
+
export const socialPaymentSourceParams = z
|
|
54
|
+
.object({
|
|
55
|
+
app: z
|
|
56
|
+
.string()
|
|
57
|
+
.min(1)
|
|
58
|
+
.max(SOCIAL_SOURCE_APP_MAX_LENGTH)
|
|
59
|
+
.regex(/^[a-z0-9][a-z0-9._-]*$/, 'source.app must be a lowercase app slug'),
|
|
60
|
+
ref: z
|
|
61
|
+
.string()
|
|
62
|
+
.min(1)
|
|
63
|
+
.max(SOCIAL_SOURCE_REF_MAX_LENGTH)
|
|
64
|
+
.regex(/^[\x21-\x7e]+$/, 'source.ref must be an opaque id, without spaces')
|
|
65
|
+
.optional(),
|
|
66
|
+
})
|
|
67
|
+
.strict();
|
|
68
|
+
/** `source` is OPTIONAL and stays that way: most person-to-person payments are for nothing in particular. */
|
|
69
|
+
export const socialNextAddressParams = z
|
|
70
|
+
.object({
|
|
71
|
+
network,
|
|
72
|
+
source: socialPaymentSourceParams.optional(),
|
|
73
|
+
})
|
|
74
|
+
.strict();
|
|
75
|
+
export const socialNextAddressSchema = defineComponent('SocialNextAddress', z
|
|
76
|
+
.object({
|
|
77
|
+
address: z.string().describe("A fresh single-use address of the recipient's."),
|
|
78
|
+
index: z.number().int().nonnegative().describe('Its social-receive derivation index.'),
|
|
79
|
+
})
|
|
80
|
+
.strict());
|
|
81
|
+
const networkQuery = z.object({ network });
|
|
82
|
+
export const socialReceiveCursorQuery = networkQuery;
|
|
83
|
+
/**
|
|
84
|
+
* Lets the caller's device resync its watch window: every `next_address`
|
|
85
|
+
* advances a monotonic index whether or not it is ever paid, so a burst of
|
|
86
|
+
* reservations can outrun a device that widens only on payment. Watch
|
|
87
|
+
* `0..reserved_through + gap`.
|
|
88
|
+
*/
|
|
89
|
+
export const socialReceiveCursorSchema = defineComponent('SocialReceiveCursor', z
|
|
90
|
+
.object({
|
|
91
|
+
reserved_through: z
|
|
92
|
+
.number()
|
|
93
|
+
.int()
|
|
94
|
+
.nonnegative()
|
|
95
|
+
.describe('The highest social-receive index ever reserved for the caller on this network; `0` when none was.'),
|
|
96
|
+
identity_public_key: z
|
|
97
|
+
.string()
|
|
98
|
+
.nullable()
|
|
99
|
+
.describe('The identity public key (hex) those addresses derive from; `null` exactly when no address was ever reserved.'),
|
|
100
|
+
})
|
|
101
|
+
.strict());
|
|
102
|
+
export const socialPaymentsQuery = networkQuery;
|
|
103
|
+
/**
|
|
104
|
+
* One social payment as the CALLER saw it — the address-free view, and the
|
|
105
|
+
* only history a surface without a key can ask for. Carries NO amount: the
|
|
106
|
+
* attribution records which address was minted, not what was paid; the amount
|
|
107
|
+
* is on-chain at `address`.
|
|
108
|
+
*/
|
|
109
|
+
export const socialPaymentSchema = defineComponent('SocialPayment', z
|
|
110
|
+
.object({
|
|
111
|
+
address: z
|
|
112
|
+
.string()
|
|
113
|
+
.describe('The single-use social-receive address minted for this payment.'),
|
|
114
|
+
direction: z.enum(SOCIAL_PAYMENT_DIRECTIONS),
|
|
115
|
+
counterparty: enrichmentResultSchema.describe("The other party; `{ kind: 'unknown' }` when the identity lookup failed."),
|
|
116
|
+
source: socialPaymentSourceSchema
|
|
117
|
+
.optional()
|
|
118
|
+
.describe('What it was for, as the paying app named it; absent when it named nothing.'),
|
|
119
|
+
created: unixSeconds.describe('When the address was minted.'),
|
|
120
|
+
})
|
|
121
|
+
.strict());
|
|
122
|
+
export const socialPaymentsSchema = defineComponent('SocialPayments', z.object({ payments: z.array(socialPaymentSchema).describe('Newest first.') }).strict());
|
|
123
|
+
export const enrichParams = z
|
|
124
|
+
.object({
|
|
125
|
+
addresses: z.array(z.string().min(1)).min(1).max(ENRICH_MAX_ADDRESSES),
|
|
126
|
+
})
|
|
127
|
+
.strict();
|
|
128
|
+
export const enrichSchema = defineComponent('Enrichment', z
|
|
129
|
+
.object({
|
|
130
|
+
data: z
|
|
131
|
+
.record(z.string(), enrichmentResultSchema)
|
|
132
|
+
.describe('Every address asked for → who is behind it.'),
|
|
133
|
+
})
|
|
134
|
+
.strict());
|
|
135
|
+
export const socialRoutes = [
|
|
136
|
+
defineRoute({
|
|
137
|
+
operationId: 'reserveSocialAddress',
|
|
138
|
+
method: 'post',
|
|
139
|
+
path: '/v1/social/{username}/next_address',
|
|
140
|
+
tag: 'Social payments',
|
|
141
|
+
summary: 'Reserve an address to pay a person',
|
|
142
|
+
description: "A fresh address of the recipient's, derived from their Oxy identity key. Limited per (sender, recipient) pair; a recipient without an identity answers 409 `keyless_recipient`; paying yourself is refused.",
|
|
143
|
+
auth: 'user',
|
|
144
|
+
params: { username: 'The recipient’s Oxy username.' },
|
|
145
|
+
body: socialNextAddressParams,
|
|
146
|
+
response: socialNextAddressSchema,
|
|
147
|
+
}),
|
|
148
|
+
defineRoute({
|
|
149
|
+
operationId: 'retrieveSocialReceiveCursor',
|
|
150
|
+
method: 'get',
|
|
151
|
+
path: '/v1/social/me/cursor',
|
|
152
|
+
tag: 'Social payments',
|
|
153
|
+
summary: "Retrieve the caller's receive cursor",
|
|
154
|
+
auth: 'user',
|
|
155
|
+
query: socialReceiveCursorQuery,
|
|
156
|
+
response: socialReceiveCursorSchema,
|
|
157
|
+
}),
|
|
158
|
+
defineRoute({
|
|
159
|
+
operationId: 'listSocialPayments',
|
|
160
|
+
method: 'get',
|
|
161
|
+
path: '/v1/social/me/payments',
|
|
162
|
+
tag: 'Social payments',
|
|
163
|
+
summary: "List the caller's social payments",
|
|
164
|
+
auth: 'user',
|
|
165
|
+
query: socialPaymentsQuery,
|
|
166
|
+
response: socialPaymentsSchema,
|
|
167
|
+
}),
|
|
168
|
+
defineRoute({
|
|
169
|
+
operationId: 'enrichAddresses',
|
|
170
|
+
method: 'post',
|
|
171
|
+
path: '/v1/enrich',
|
|
172
|
+
tag: 'Social payments',
|
|
173
|
+
summary: 'Resolve who is behind addresses',
|
|
174
|
+
description: 'Display-only counterparty identity for the caller’s own payments; never affects custody.',
|
|
175
|
+
auth: 'user',
|
|
176
|
+
body: enrichParams,
|
|
177
|
+
response: enrichSchema,
|
|
178
|
+
}),
|
|
179
|
+
];
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { defineRoute } from '../../route.js';
|
|
3
|
+
import { SIMULATED_FAIRCOIN_OUTCOMES } from '../../vocabulary/payments.js';
|
|
4
|
+
import { paymentIntentSchema } from './paymentIntents.js';
|
|
5
|
+
/**
|
|
6
|
+
* Test helpers for payment intents — test mode only. They drive a test-mode
|
|
7
|
+
* payment through the SAME state machine a real one moves through, with the
|
|
8
|
+
* same events and webhooks, so an integration is exercised end to end without
|
|
9
|
+
* a wallet.
|
|
10
|
+
*/
|
|
11
|
+
export const simulateFaircoinPaymentParams = z
|
|
12
|
+
.object({
|
|
13
|
+
outcome: z
|
|
14
|
+
.enum(SIMULATED_FAIRCOIN_OUTCOMES)
|
|
15
|
+
.optional()
|
|
16
|
+
.describe('`settled` (the default): paid in full, seen and confirmed. `underpaid`: less than the amount arrived.'),
|
|
17
|
+
})
|
|
18
|
+
.strict();
|
|
19
|
+
export const paymentIntentTestHelperRoutes = [
|
|
20
|
+
defineRoute({
|
|
21
|
+
operationId: 'simulateFaircoinPayment',
|
|
22
|
+
method: 'post',
|
|
23
|
+
path: '/v1/test_helpers/payment_intents/{id}/simulate_faircoin_payment',
|
|
24
|
+
tag: 'Test helpers',
|
|
25
|
+
summary: 'Simulate a FairCoin payment',
|
|
26
|
+
description: 'Pretend the payer broadcast and the chain confirmed (or underpaid) a FairCoin payment in `requires_action`. A live credential is refused with 403 `test_mode_only`.',
|
|
27
|
+
auth: 'service',
|
|
28
|
+
scope: 'payments:write',
|
|
29
|
+
idempotent: true,
|
|
30
|
+
testModeOnly: true,
|
|
31
|
+
params: { id: 'The payment intent (`pi_…`).' },
|
|
32
|
+
body: simulateFaircoinPaymentParams,
|
|
33
|
+
response: paymentIntentSchema,
|
|
34
|
+
sdk: 'testHelpers.paymentIntents.simulateFaircoinPayment',
|
|
35
|
+
}),
|
|
36
|
+
];
|