Payment state queries

Corda stores the state of a payment in the vault of the node that initiated the payment, so you can access the state of a payment by querying the vault.

classDiagram
  class MyPaymentService {
    + queryPaymentsViaGevamu()
  }
  class GevamuFacade {
    + getPayment()
    + queryPayments()
  }

  MyPaymentService ..> GevamuFacade
Mermaid diagram is loading...

Payment state structure

The structure of the Payment state is as follows:

classDiagram
  class Payment {
    + payer: Party
    + gateway: Party
    + endToEndId: String
    + paymentInstructionId: AttachmentId
    + status: PaymentStatus
    + additionalInfo: String?
    + uniquePaymentId: UUID
    + timestamp: Instant
  }

  class PaymentStatus{
    <<enumeration>>
    CREATED
    SENT_TO_GATEWAY
    ACCEPTED
    PENDING
    COMPLETED
    REJECTED
  }

  class Attachment {
    <<interface>>
    + id: SecureHash
    + open(): InputStream
  }

  Payment o-- PaymentStatus
  Payment .. Attachment: paymentInstructionId --> id
Mermaid diagram is loading...

Note that a full payment instruction is stored as a Corda Attachment.

Vault queries

Every Corda node has a vault that stores all the states created by the node (in our case, the Payment states).

Corda provides a powerful query language to search for states in the vault – learn more about Writing vault queries in Corda documentation.

Gevamu SDK doesn't provide any ready-to-use solution for querying by payments details stored in the attachment. However, you can create additional tables with the information specific to your business needs and use them in vault queries. To get all payment details from the attachment, download and deserialize it.

To create queries for the Gevamu payments, use the following imports:

// Corda imports
import net.corda.core.node.services.vault.QueryCriteria
// Gevamu SDK imports
import com.gevamu.corda.schema.PaymentSchemaV1
import com.gevamu.corda.states.Payment

Getting a single payment

To find a unique payment, search by the uniquePaymentId field, accepted by the getPayment method as a parameter.

import java.util.UUID
import net.corda.core.node.services.vault.QueryCriteria
import com.gevamu.corda.schema.PaymentSchemaV1
import com.gevamu.corda.states.Payment
class GevamuFacade {
fun getPayment(uniquePaymentId: UUID): StateAndRef<Payment>? {
// Create custom query criteria to search by id
val criteria = QueryCriteria.VaultCustomQueryCriteria(
// Pay attention to method `equal` here. It is not `equals`!
PaymentSchemaV1.PersistentPayment::uniquePaymentId.equal(uniquePaymentId)
)
// Query vault and return single payment state
return serviceHub.vaultService.queryBy<Payment>(criteria).states.singleOrNull()
}
}

Payment queries

Search criteria for payments can be unique to particular business use cases. The following example shows a generic method for querying payments.

import net.corda.core.node.services.vault.QueryCriteria
import com.gevamu.corda.states.Payment
class GevamuFacade {
fun queryPayments(criteria: QueryCriteria): List<StateAndRef<Payment>> {
// Query vault and return list of payment states
return serviceHub.vaultService.queryBy<Payment>(criteria).states
}
}

Payment queries by date range

Querying objects by a date range is a common task for different business domains. The following example shows how to implement this functionality in relation to the Gevamu Payment solution:

import java.time.Instant
import net.corda.core.node.services.vault.QueryCriteria
import com.gevamu.corda.schema.PaymentSchemaV1
import com.gevamu.corda.states.Payment
class GevamuFacade {
fun queryPaymentsByDateRange(from: Instant, to: Instant): List<StateAndRef<Payment>> {
// Create custom query criteria to search by date range
val criteria = QueryCriteria.VaultCustomQueryCriteria(
PaymentSchemaV1.PersistentPayment::timestamp.between(from, to)
)
// Query vault and return list of payment states
return serviceHub.vaultService.queryBy<Payment>(criteria).states
}
}