Payment service flows

Use Payment Service flows to initiate payments and account management requests from a node on a Corda network. These requests can then be picked up by the Payments Agent on your network.

Use the Payment Service flows to:

Initiate a payment between participating nodes on the network.

  • amount: Amount<FiatCurrency>. Required. The amount and currency of the payment to make. In the Corda Payments Technical Preview, you can use GBP or EUR.
  • debtor: String. Required. A reference (signature) to debtor account (the account from which the payment is to be made—or the account from which makePaymentis initiated) which is in turn resolved by the AccountsResolver service.
  • creditor: String. Required. A reference (signature) to creditor account (the account into which the payment is to be made) which is in turn resolved by the AccountsResolver service.
  • transactionRef: String. Provided reference to the specified transaction. Bound to the externalId of the generated PaymentState’s UniqueIdentifier. Should be unique.
  • externalId: String. Corresponds to the ID provided by the PSP.

PaymentState - The object containing information regarding the requested payment.

@StartableByRPC
@StartableByService
class MakePayment(
private val amount: Amount,
private val debtor: PaymentAccountId,
private val creditor: PaymentAccountId,
private val externalRef: String?,
private val transactionRef: String?,
private val details: Map<String, Any>,
private val comments: List?
) : FlowLogic()

val paymentState = proxy.startTrackedFlow(
::MakePayment,
1 of GBP,
accountB.accountId,
accountA.accountId
).returnValue.getOrThrow()\

Reinstate a stalled payment into the payment workflow.

  • paymentId UUID. ID of the stalled payment to be reinstated.
  • comment String. User supplied comment.

PaymentState - The object containing information regarding the requested payment.

@StartableByRPC
@StartableByService
class ReinstatePayment(
private val uuid: UUID,
private val commandName: String,
private val comment: String?
) : ReinstatePaymentInitiator()
val paymentState = proxy.startTrackedFlow(
::ReinstatePayment,
paymentId,
PaymentCommands.ManuallyFixedPayment(),
comment
).returnValue.getOrThrow()

Cancel a stalled payment.

  • paymentId UUID. Payment ID of the stalled payment.
  • comment String. User supplied comment.

PaymentState - The object containing information regarding the requested payment.

Both retrying a stalled payment and cancelling a stalled payment use the same flow with a different command attached.

@StartableByRPC
@StartableByService
class ReinstatePayment(
private val uuid: UUID,
private val commandName: String,
private val comment: String?
) : ReinstatePaymentInitiator()
val paymentState = proxy.startTrackedFlow(
::ReinstatePayment,
paymentId,
PaymentCommands.ManuallyFailed(),
comment
).returnValue.getOrThrow()

Update a stalled payment and reinstate into the payment workflow.

  • payment The updated payment state.

PaymentState - The object containing information regarding the requested payment.

@StartableByRPC
@StartableByService
class RemediatePayment(
private val updatedPayment: PaymentState,
private val commandName: String
) : RemediatePaymentInitiator()
val tx = service.startFlow(
    ::RemediatePayment,
    updatedState,
    "ManuallyFixedPayment").returnValue.get()

Return a list of payments stalled on an error.

None.

List of PaymentState objects for payments stalled on an error.

@StartableByRPC
@StartableByService
class StalledPayments : FlowLogic<List<PaymentState>>()
flowAwareStartFlow(StalledPayments()).getOrThrow()

Return the PaymentState associated with either a paymentId or transactionRef.

You can use either of the following:

  • paymentId: UUID. The unique identifier component of the PaymentState.

  • transactionRef UUID. The externalId component of the target PaymentState.

  • PaymentState - Object containing information regarding the requested payment.
@StartableByRPC
@StartableByService
class PaymentById private constructor(
	private val transactionRef: String?,
	private val paymentId: UUID?
) : FlowLogic<List<PaymentState>>()
flowAwareStartFlow(PaymentById(paymentId)).getOrThrow()

Get a list of the Payment Service Providers (PSPs) that are registered on the sent node—making them available for payments on your network.

None.

List<PSPSpecification>. A list of PSP identifiers, such as “MODULR”, that are available on the system to make payments against.

@StartableByRPC
@StartableByService
class AvailablePSPs : AvailablePSPsInitiator()
flowAwareStartFlow(AvailablePSPs()).getOrThrow()

Return the PSP specification for the named PSP on the agent. In the Corda Payments Technical Preview, the PSP can only be Modulr.

  • name. The name of the PSP.
@StartableByRPC
@StartableByService
class AvailablePSPs : AvailablePSPsInitiator()
flowAwareStartFlow(AvailablePSPs()).getOrThrow()

Create a record of an existing payment account in the application.

  • accountName: String. Account name to be stored against the account details that are received from the PSP (Modulr).

  • currency: FiatCurrency. The currency that the account should be created with.

  • psp: String. The PSP to create the account with. In Corda Payments Technical Preview, this can only be Modulr.

  • agent: Party [Optional]. The Payments Agent on your network. If not provided, the account will default to an agent configured via the node’s Payment Service CorDapp config.

  • details: Map<String, String> [Optional]. Additional Key-value data associated with the Payment Account. These details will be stored in the underlying PaymentAccountDetailsState shared between agent and node. They are not available through the returned PaymentAccount object.

PaymentAccount: Object. The payment account details.

@StartableByRPC
@StartableByService
class AddPaymentAccount(
	private val accountName: String,
	private val currency: FiatCurrency,
	private val psp: String,
	private val pspAccountId: String,
	private val credentials: Map<String, String>
) : FlowLogic<PaymentAccount>()
service.startFlow(
    ::AddPaymentAccount,
    accountName,
    FiatCurrency(currency),
    psp,
    accountId,
    authDetails).returnValue.get()

Create a record of payment account linked to a specific customer in the application.

  • accountName. A common name for the account

  • currency. The currency of the account

  • psp. Payment Service Provider associated with this account

  • customerId. ID of the customer who owns the account. You should get this information from the Payments Agent on your network.

  • pspAccountId. Original accountId on PSP for re-registered accounts.

PaymentAccount: Object. The payment account details.

@StartableByRPC
@StartableByService
class AddCustomerAccount(
private val accountName: String,
private val currency: FiatCurrency,
private val psp: String,
private val customerId: PaymentCustomerId,
private val pspAccountId: String?
) : FlowLogic<PaymentAccount>()
service.startFlow(
    ::AddCustomerAccount,
    accountName,
    FiatCurrency(currency),
    psp,
    customerId,
    accountId).returnValue.get()

Create a local record of a beneficiary payment account for a party that is not present on the network.

  • accountName. A common name for the account.
  • currency. The currency required for the account.
  • psp. Payment Service Provider associated with this account.
  • details. Additional key-value data to be stored.

PaymentAccount: Object. Contains details of the payment account.

@StartableByRPC
@StartableByService
class AddBeneficiaryAccount(
	private val accountName: String,
	private val currency: FiatCurrency,
	private val psp: String,
	private val details: Map<String, String>
) : AddBeneficiaryAccountInitiator()
service.startFlow(
    ::AddBeneficiaryAccount,
    accountName,
    FiatCurrency(currency),
    psp,
    details).returnValue.get()

Send a request to update the underlying PaymentAccountDetailsState with the provided details.

  • details: Map<String, String>. Additional Key-value data associated with the Payment Account. These details are stored in the underlying PaymentAccountDetailsState shared between agent and node—but are not available through the returned PaymentAccount object.

PaymentAccount: Object. The payment account details.

@StartableByRPC
@StartableByService
class UpdatePaymentAccount(
    private val accountId: PaymentAccountId,
    private val credentials: Map<String, String>
): FlowLogic<PaymentAccount>()
service.startFlow(
    ::UpdatePaymentAccount,
    account.accountId,
    authDetails).returnValue.get()

Update a beneficiary payment account details. If an existing key is provided in details, the value will be updated. If a new key is provided, a new entry in the map will be created.

  • accountId. The unique account identifier.
  • details: Map<String, String>. Additional Key-value data associated with the Payment Account. These details are stored in the underlying PaymentAccountDetailsState shared between agent and node—but are not available through the returned PaymentAccount object.

PaymentAccount: Object. The payment account details.

@StartableByRPC
@StartableByService
class UpdateBeneficiaryAccount(
    private val accountId: PaymentAccountId,
    private val details: Map<String, String>
): FlowLogic<PaymentAccount>()
service.startFlow(
    ::UpdateBeneficiaryAccount,
    account.accountId,
    details).returnValue.get()

Get a list of PaymentAccounts for all the accounts owned by the party passed as a parameter.

The AccountDetails object captures the owning key for these details which could refer to a well-known party or Corda account.

owningParty: AbstractParty - the owning party of the payment accounts.

List<PaymentAccount> - The list of internal account references. Returns an empty list if none exist.

@StartableByRPC
@StartableByService
class PaymentAccounts(
	private val owningParty: AbstractParty
) : PaymentAccountsInitiator()
service.startFlow(
    ::PaymentAccounts,
    ownerParty).returnValue.get()

Get the PaymentAccount associated with a unique account identifier (signature).

accountId: String. A type of PaymentAccountId.

PaymentAccount: The payment account object.

@StartableByRPC
@StartableByService
class PaymentAccountById(private val accountId: PaymentAccountId) : PaymentAccountByIdInitiator()
service.startFlow(
    ::PaymentAccountById,
    accountId).returnValue.get()

Return a list of transactions made against this account as recorded on the PSP, using the criteria given to this function.

  • accountId. The identifier of the account which is involved as debtor or creditor.
  • searchCriteria. Optional criteria to further filter transaction search.

PagedResponse<PaymentTransaction>. A paged response of transactions.

@StartableByRPC
@StartableByService
class Transactions(
	private val accountId: PaymentAccountId,
	private val searchCriteria: PaymentTransactionCriteria
) : TransactionsInitiator()
service.startFlow(
    ::Transactions,
    accountId,
    searchCriteria).returnValue.get()

Return a list of transactions made against this account as recorded on the vault, using the criteria given to this function.

  • accountId. The identifier of the account which is involved as debtor OR creditor.
  • searchCriteria. Optional criteria to further filter transaction search.

PagedResponse<PaymentTransaction>. A paged response of transactions.

@StartableByRPC
@StartableByService
class Payments(
    private val accountId: PaymentAccountId,
    private val searchCriteria: PaymentTransactionCriteria
) : FlowLogic<PagedResponse<PaymentTransaction>>()
service.startFlow(
    ::Payments,
    accountId,
    searchCriteria).returnValue.get()

Get the account balance for a given payment account ID.

accountId : String. The payment account ID.

AccountBalance. The balance of the requested account.

@StartableByRPC
@StartableByService
class ViewAccountBalance(
		private val accountId: PaymentAccountId
): AccountBalanceInitiator()
service.startFlow(
  ::ViewAccountBalance,
  account.accountId).returnValue.get()

Returns the current default payments agent, if it has been set. The default payments agent can be set through CorDapp config.

None.

AbstractParty.

Was this page helpful?

Thanks for your feedback!

Chat with us

Chat with us on our #docs channel on slack. You can also join a lot of other slack channels there and have access to 1-on-1 communication with members of the R3 team and the online community.

Propose documentation improvements directly

Help us to improve the docs by contributing directly. It's simple - just fork this repository and raise a PR of your own - R3's Technical Writers will review it and apply the relevant suggestions.

We're sorry this page wasn't helpful. Let us know how we can make it better!

Chat with us

Chat with us on our #docs channel on slack. You can also join a lot of other slack channels there and have access to 1-on-1 communication with members of the R3 team and the online community.

Create an issue

Create a new GitHub issue in this repository - submit technical feedback, draw attention to a potential documentation bug, or share ideas for improvement and general feedback.

Propose documentation improvements directly

Help us to improve the docs by contributing directly. It's simple - just fork this repository and raise a PR of your own - R3's Technical Writers will review it and apply the relevant suggestions.