Skip to main content

Overview

Payment capture is the final step in the payment process where funds are transferred from the customer to the merchant. Openfront supports automatic payment capture through cart completion and manual capture for invoices.

Complete Active Cart

Finalize a cart and capture payment to create an order.

GraphQL Mutation

mutation CompleteActiveCart(
  $cartId: ID!
  $paymentSessionId: ID
) {
  completeActiveCart(
    cartId: $cartId
    paymentSessionId: $paymentSessionId
  )
}
cartId
ID
required
Unique identifier of the cart to complete
paymentSessionId
ID
Payment session ID for paid orders. Omit for account/customer token orders (Openship flow)

Response

Returns a complete order object:
id
string
Order unique identifier
displayId
number
Human-readable order number
status
string
Order status (“pending” after creation)
total
string
Total order amount
subtotal
string
Subtotal before tax and shipping
tax
string
Tax amount
shipping
string
Shipping cost
secretKey
string
Secret key for guest order tracking (only for guest orders)
shippingAddress
object
Delivery address details

Payment Flows

The completeActiveCart mutation handles two different payment flows:

1. Paid Orders (Regular Storefront)

mutation {
  completeActiveCart(
    cartId: "cart_123"
    paymentSessionId: "session_456"
  )
}
For regular storefront orders with payment processing:
  • Requires paymentSessionId
  • Captures payment through Stripe, PayPal, or manual payment
  • Creates payment record with status “captured” or “pending”
  • Order is created immediately

2. Account Orders (Openship/Business Accounts)

mutation {
  completeActiveCart(
    cartId: "cart_123"
    # No paymentSessionId
  )
}
For business account orders:
  • No paymentSessionId provided
  • Requires authenticated user with active business account
  • Validates credit limit before creating order
  • Adds order to account as unpaid line item
  • No immediate payment capture

Example - Complete Cart with Stripe Payment

mutation {
  completeActiveCart(
    cartId: "cart_abc123"
    paymentSessionId: "session_xyz789"
  )
}

Payment Status in Orders

When a payment is captured, the following occurs:
  1. Payment record created with status “captured”
  2. Capture record created linking to the payment
  3. Order payment status updated to “captured”
  4. Order event created with type “PAYMENT_CAPTURED”

Complete Invoice Payment

Capture payment for an invoice.

GraphQL Mutation

mutation CompleteInvoicePayment($paymentSessionId: ID!) {
  completeInvoicePayment(paymentSessionId: $paymentSessionId) {
    id
    status
    success
    message
    error
  }
}
paymentSessionId
ID
required
Payment session ID associated with the invoice

Response

id
string
Invoice unique identifier
status
string
Invoice status after payment
success
boolean
Whether payment was successful
message
string
Success or error message
error
string
Error details if payment failed

Example

mutation {
  completeInvoicePayment(paymentSessionId: "session_inv_123") {
    id
    status
    success
    message
  }
}

Pay Invoice (Alternative Method)

Pay an invoice with custom payment data.

GraphQL Mutation

mutation PayInvoice(
  $invoiceId: ID!
  $paymentData: PaymentInput!
) {
  payInvoice(invoiceId: $invoiceId, paymentData: $paymentData) {
    success
    invoice {
      id
      status
    }
    payment {
      id
      status
      amount
    }
    message
    error
  }
}
invoiceId
ID
required
Invoice unique identifier
paymentData
PaymentInput
required
Payment information
paymentMethod
String
required
Payment method identifier
paymentMethodId
String
Provider-specific payment method ID
data
JSON
Additional payment data

Response

success
boolean
Payment success status
invoice
object
Updated invoice object
payment
object
Created payment record
message
string
Result message
error
string
Error details if failed

Manual Payment Update

Update payment status directly (requires admin permissions):
mutation UpdatePayment(
  $where: PaymentWhereUniqueInput!
  $data: PaymentUpdateInput!
) {
  updatePayment(where: $where, data: $data) {
    id
    status
    amount
    capturedAt
    order {
      id
      paymentStatus
    }
  }
}

Payment Status Transitions

Valid payment status values:
pending
string
Payment initiated but not processed
authorized
string
Payment authorized but not captured
captured
string
Payment successfully captured (triggers automatic capture record creation)
failed
string
Payment processing failed
canceled
string
Payment canceled

Example - Capture Authorized Payment

mutation {
  updatePayment(
    where: { id: "payment_123" }
    data: { status: "captured" }
  ) {
    id
    status
    capturedAt
    order {
      paymentStatus
    }
  }
}
When status is updated to “captured”, the system automatically:
  • Sets capturedAt timestamp
  • Creates a Capture record
  • Updates order paymentStatus to “captured”
  • Creates an order event “PAYMENT_CAPTURED”

Payment Provider Integration

Stripe Payment Capture

Stripe payments are captured automatically in completeActiveCart:
  1. Payment intent retrieved from session data
  2. Payment status checked
  3. If requires_capture, payment is captured via Stripe API
  4. Payment record created with status “captured”

PayPal Payment Capture

PayPal payments are verified in completeActiveCart:
  1. PayPal order verified via API
  2. Order status checked (COMPLETED or APPROVED)
  3. Payment record created with status “captured”

Manual Payments

For cash on delivery or manual payment methods:
  1. Payment record created with status “manual_pending”
  2. Order created successfully
  3. Payment can be manually updated to “captured” later

Webhook Handling

Handle payment provider webhooks for asynchronous payment updates:
mutation HandlePaymentProviderWebhook(
  $providerId: ID!
  $event: JSON!
  $headers: JSON!
) {
  handlePaymentProviderWebhook(
    providerId: $providerId
    event: $event
    headers: $headers
  ) {
    success
    message
    statusCode
    error
  }
}
providerId
ID
required
Payment provider identifier
event
JSON
required
Webhook event data from payment provider
headers
JSON
required
HTTP headers for signature verification

Build docs developers (and LLMs) love