-
Notifications
You must be signed in to change notification settings - Fork 10
feat: add rule-based internal accounts and the sweep failure webhook #891
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
26f0870
feat: add rule-based internal accounts and the sweep failure webhook
bsiaotickchong 3263332
feat: create internal accounts at POST /internal-accounts
bsiaotickchong 7f85174
fix: require sweepRule on the create request
bsiaotickchong ed7c115
docs: say sweep, and drop the held-in-account outcome
bsiaotickchong 7426a03
docs: describe rule-based accounts by their holder, not the customer
bsiaotickchong dbde6cf
docs: carry one transaction id on a sweep failure
bsiaotickchong eee2a47
docs: make customerId optional so the endpoint stays generic
bsiaotickchong 82beb24
docs: carry the sweep outcome on the transaction, not its own webhook
bsiaotickchong d170b60
docs: let a transaction exist before its amount is priced
bsiaotickchong 9068708
docs: make sweepRule optional and pin the corridor bound currency
bsiaotickchong d036f66
docs: say how sweepFailureReason and failureReason relate
bsiaotickchong 004fba4
docs: fail the transaction when its sweep does not complete
bsiaotickchong 75b0de2
docs: use the reviewer's receivedAmount wording
bsiaotickchong 32ce372
docs: trim the sweep failure reasons to three
bsiaotickchong a6c0591
docs: fold the sweep rail failure into ACCOUNT_CANNOT_RECEIVE
bsiaotickchong 2eeefcf
docs: drop the failureReason sweep note
bsiaotickchong File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
48 changes: 48 additions & 0 deletions
48
openapi/components/schemas/customers/InternalAccountCreateRequest.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| title: Internal Account Create Request | ||
| type: object | ||
| description: >- | ||
| Request body for `POST /internal-accounts`. Only `RULE_BASED` accounts can be | ||
| created today, and they are rejected without a `sweepRule` — the type and its | ||
| rule are created together or not at all. | ||
| additionalProperties: false | ||
| required: | ||
| - type | ||
| - currency | ||
|
ls-bolt[bot] marked this conversation as resolved.
|
||
| properties: | ||
| customerId: | ||
| type: string | ||
| description: >- | ||
| The customer the account is created for. Omit it to create a | ||
| platform-owned account. The account holder must already have a verified | ||
| account in the same currency, which is where funds land when a sweep | ||
| cannot be completed. Platform-owned rule-based accounts are not available | ||
| yet, so omitting this is currently rejected. | ||
| example: Customer:019542f5-b3e7-1d02-0000-000000000001 | ||
| type: | ||
| allOf: | ||
| - $ref: ./InternalAccountType.yaml | ||
| description: >- | ||
| Must be `RULE_BASED`. `INTERNAL_FIAT`, `INTERNAL_CRYPTO`, and | ||
| `EMBEDDED_WALLET` accounts are provisioned automatically when a customer | ||
| is created or approved, so they cannot be created through this endpoint. | ||
| example: RULE_BASED | ||
| currency: | ||
| type: string | ||
| description: >- | ||
| Currency code the account is denominated in (ISO 4217). Rule-based | ||
| accounts are currently available in `USD` only. | ||
| example: USD | ||
| label: | ||
| type: string | ||
| maxLength: 255 | ||
| description: >- | ||
| Your own name for the account, echoed back on reads. Useful for | ||
| identifying which payer the account was issued for. | ||
| example: invoice-4417 | ||
| sweepRule: | ||
| allOf: | ||
| - $ref: ./SweepRuleRequest.yaml | ||
| description: >- | ||
| The routing rule for the account. Required when `type` is `RULE_BASED`, | ||
| which is the only type this endpoint creates today: a rule-based account | ||
| with no rule has no meaning, so the two are written together. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| title: Sweep Rule | ||
| type: object | ||
| description: >- | ||
| The routing rule attached to a rule-based account. Returned on the account | ||
| rather than as a resource of its own, because the rule has no lifecycle apart | ||
| from the account. | ||
| required: | ||
| - destination | ||
| properties: | ||
| destination: | ||
| allOf: | ||
| - $ref: SweepRuleDestination.yaml | ||
| description: Where funds that settle into this account are swept. | ||
| minimumAmount: | ||
| allOf: | ||
| - $ref: ../common/CurrencyAmount.yaml | ||
| description: >- | ||
| **In this rule-based account's currency, not the destination's.** The | ||
| smallest balance the corridor to the destination can carry; a settled | ||
| balance below it is not swept. Zero means no floor, which is the case for | ||
| a same-currency internal destination — a book transfer with no rail, fee | ||
| or conversion to justify one. Configuration rather than a moving | ||
| estimate, so there is nothing to re-poll. | ||
| maximumAmount: | ||
| allOf: | ||
| - $ref: ../common/CurrencyAmount.yaml | ||
| description: >- | ||
| **In this rule-based account's currency, not the destination's.** The | ||
| largest balance the corridor to the destination can carry; a settled | ||
| balance above it is not swept. Null means no ceiling. | ||
| purposeOfPayment: | ||
| allOf: | ||
|
bsiaotickchong marked this conversation as resolved.
|
||
| - $ref: ../quotes/PurposeOfPayment.yaml | ||
| description: The purpose of payment applied to each sweep. | ||
| example: SELF | ||
| description: | ||
| type: string | ||
| description: >- | ||
| Free-form description recorded on each sweep. Not delivered to the | ||
| recipient. | ||
| example: Rent sweep | ||
| remittanceInformation: | ||
| type: string | ||
| description: >- | ||
| Free-form information that travels with each sweep to the recipient. | ||
| example: Unit 4B March | ||
| platformFeeOverride: | ||
| allOf: | ||
| - $ref: ../quotes/PlatformFeeOverride.yaml | ||
| description: >- | ||
| Fee terms applied to every sweep this rule drives. Null when the | ||
| platform's configured fees apply. | ||
18 changes: 18 additions & 0 deletions
18
openapi/components/schemas/customers/SweepRuleDestination.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| title: Sweep Rule Destination | ||
| type: object | ||
| description: >- | ||
| Where a rule-based account's credits are swept. | ||
| required: | ||
| - accountId | ||
| properties: | ||
| accountId: | ||
| type: string | ||
| description: The account that receives the swept funds. | ||
| example: ExternalAccount:a12dcbd6-dced-4ec4-b756-3c3a9ea3d123 | ||
| paymentRail: | ||
| allOf: | ||
| - $ref: ../common/PaymentRail.yaml | ||
| description: >- | ||
| The rail each sweep is sent over. Null when a rail is selected | ||
| automatically per sweep, in which case none is resolved ahead of time. | ||
| example: ACH |
25 changes: 25 additions & 0 deletions
25
openapi/components/schemas/customers/SweepRuleDestinationRequest.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| title: Sweep Rule Destination Request | ||
| type: object | ||
| description: >- | ||
| The account a rule-based account sweeps its incoming payments to. | ||
| additionalProperties: false | ||
| required: | ||
| - accountId | ||
| properties: | ||
| accountId: | ||
| type: string | ||
| description: >- | ||
| Reference to the account that receives the swept funds. May be an | ||
| external account or another internal account, but never a `RULE_BASED` | ||
| internal account — that account's own rule would sweep the funds on | ||
| again. The destination may be denominated in a different currency, in | ||
| which case the sweep is converted at the prevailing rate. | ||
| example: ExternalAccount:e85dcbd6-dced-4ec4-b756-3c3a9ea3d965 | ||
| paymentRail: | ||
| description: >- | ||
| The payment rail to use when sweeping to an external account. Must be | ||
| one of the rails supported by the destination account. If omitted, a rail | ||
| is selected automatically for each sweep. Not accepted when the | ||
| destination is an internal account, which settles without a payment rail. | ||
| allOf: | ||
| - $ref: ../common/PaymentRail.yaml |
40 changes: 40 additions & 0 deletions
40
openapi/components/schemas/customers/SweepRuleRequest.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| title: Sweep Rule Request | ||
| type: object | ||
| description: >- | ||
| The routing rule attached to a rule-based account. Every payment that settles | ||
| into the account is swept to the rule's destination, carrying the payment | ||
| metadata configured here. | ||
| additionalProperties: false | ||
| required: | ||
| - destination | ||
| properties: | ||
| destination: | ||
| allOf: | ||
| - $ref: ./SweepRuleDestinationRequest.yaml | ||
| description: Where funds that settle into this account are swept. | ||
| purposeOfPayment: | ||
| allOf: | ||
| - $ref: ../quotes/PurposeOfPayment.yaml | ||
| description: >- | ||
| The purpose of payment applied to each sweep. Required by some | ||
| destination geographies. | ||
| example: SELF | ||
| description: | ||
| type: string | ||
| maxLength: 255 | ||
| description: >- | ||
| Free-form description recorded on each sweep. Not delivered to the | ||
| recipient; use `remittanceInformation` for that. | ||
| example: Rent sweep | ||
| remittanceInformation: | ||
| type: string | ||
| maxLength: 1024 | ||
| description: >- | ||
| Free-form information that travels with each sweep to the recipient. | ||
| The field this populates depends on the payment rail: for ACH it | ||
| populates the Addenda record, for FedNow and RTP it populates the | ||
| remittanceInformation field, and for wires it populates the OBI | ||
| (Originator to Beneficiary Information) / beneficiary information. Only | ||
| printable ASCII characters are accepted, because the underlying rails | ||
| carry nothing else. | ||
| example: Unit 4B March |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.