Skip to main content
You are viewing early implementations that may change before release. Use them to prepare and provide feedback to our team. Check out Swan's public roadmap to see what else is in the works.

Create in-person card payments

Create payment intents so your merchants can accept card payments from customers using their terminal app.

Prerequisites

Step 1: Create a payment intent

Call the createInPersonPaymentIntent mutation to create a payment intent. The mutation returns a secret (Stripe's client secret) that you'll use in the next step with the Stripe SDK.

mutation CreateInPersonPayment {
createInPersonPaymentIntent(
input: {
merchantProfileId: "$YOUR_MERCHANT_PROFILE_ID"
amount: { value: "50", currency: "EUR" }
label: "Payment for order #1234"
externalReference: "order-1234"
}
) {
... on CreateInPersonPaymentIntentSuccessPayload {
paymentIntent {
secret
}
}
... on ForbiddenRejection {
__typename
message
}
... on NotFoundRejection {
__typename
message
}
... on InternalErrorRejection {
__typename
message
}
... on ValidationRejection {
__typename
message
}
}
}

Mutation fields

Field Requirements Legend

● REQ Required:Must be completed.
◐ CND Conditional:Required only in specific situations.
○ OPT Optional:Isn't required; may have a default value.
FieldTypeDescription
merchantProfileIdID● REQID of the merchant profile accepting the payment.
amountAmountInput● REQAmount for the payment intent. Minimum: €0.50.
labelString○ OPTLabel shown on the merchant's bank statement.
externalReferenceString○ OPTReference to match the payment with an external system, such as an order ID.
referenceString○ OPTPayment reference.
idempotencyKeyString○ OPTUnique key to prevent duplicate payment creation.

Step 2: Process the payment with the Stripe SDK

After creating the payment intent, use the Stripe Terminal SDK in your terminal app to collect and confirm the payment. This step runs entirely on the device.

2.1: Retrieve the payment intent

Use the secret from step 1 to retrieve the payment intent with the Stripe SDK.

const secret = "$PAYMENT_INTENT_SECRET"; // from step 1
const { paymentIntent, error } = await retrievePaymentIntent(secret);
if (error) {
// Handle error
return;
}

2.2: Collect the payment method

Call collectPaymentMethod to show the Tap to Pay screen. This activates the device's NFC reader and prompts the customer to tap their card.

const { paymentIntent, error } = await collectPaymentMethod({
paymentIntent: paymentIntent,
enableCustomerCancellation: true,
});
if (error) {
// Handle error
}

2.3: Confirm the payment intent

Call confirmPaymentIntent to finalize the payment. The payment is authorized and captured automatically.

Retrying a failed capture

If capture fails and you want to offer a retry (for example, with a different card), reuse the same payment intent. Repeat step 2.2, then attempt to confirm again.

const { paymentIntent, error } = await confirmPaymentIntent({
paymentIntent: paymentIntent,
});
if (error) {
// Handle error
}

Merchant payment statuses

After processing, the merchant payment object reflects the payment's lifecycle. Refer to the payment object statuses for the full list.

StatusExplanation
CapturedPayment authorized and captured. Funds will be settled to the merchant's account.
RejectedPayment declined by the issuer or by Swan. Refer to rejection reasons for details.
DisputedCustomer disputed the payment for some or all of the amount.
RefundedPayment reversed by the merchant for some or all of the amount.

After the payment

After the payment is captured, the merchant payment object is updated and underlying transactions are created. Refer to card transaction types to understand how they settle.

Refunds not supported

Refunds are currently not supported for in-person card payments. To initiate a refund, ask your merchant to submit a request to the Swan Support team.