Card Payments
Take card payments through the API
To use this capability add octo/cardPayments
to your Octo-Capabilities
header.
This capability allows you to accept card payments via the API. It is possible to support multiple gateways, we document 4 in this spec: VivaWallet
Adyen
Stripe
and External
If you want us to add support for any other gateway please contact us at dev@ventrata.com
Adyen Gateway
We add a cardPayment
key to the booking object, but if you're using the octo/cart
capability then we add the same key to that as well. The value will look like this:
In the response we provide all the values required to initialize Adyen's Drop-in Widget which you can find documented here:
The session
field will be null
until you have provided a returnUrl
field on the order which will be used by the Adyen integration to redirect the guest after the payment is complete.
Following that the response body will include the session data like so:
Once complete, and you're ready to confirm the order/booking then you must replay the sessionId back to the API like so:
POST /bookings/:uuid/confirm
POST /orders/:orderId/confirm
If Ventrata hasn't yet received the webhook notification from Adyen then you may receive a PAYMENT_PENDING
error code returned, you can just repeat the confirm request until it works. If the payment is refused, you'll get a BAD_REQUEST
error with the error message in the errorMessage
field and a new session
will be generated for you to try again with.
VivaWallet Gateway
We add a cardPayment
key to the booking object, but if you're using the octo/cart
capability then we add the same key to that as well. The value will look like this:
In the response we provide orderCode
value which you can use to initiate the VivaWallet Smart Checkout as described in the documentation here:
As described in the docs, in production you just redirect the guest to a URL like so:
https://www.vivapayments.com/web2?ref=1272214778972604
Where the value for ref
is the orderCode
returned in the card payment object. The documentation also describes various ways to customise the checkout including using custom colors and payment methods.
Once the payment is complete, the customer will be redirected back to the Success URL or Failure URL as setup in your gateway account. If directed to the Success URL you will also receive a query parameter t
which is a UUID (example t=2b4c6b5b-49ff-4e46-adc5-f53740212361
), you must then send this to Ventrata along with the original orderCode
using either of the confirmation endpoints (depending if you're using the octo/cart
capability):
POST /bookings/:uuid/confirm
POST /orders/:orderId/confirm
Ventrata will then verify the payment has actually been approved and if so will confirm the order.
Bridgepay Gateway
We add a cardPayment
key to the booking object, but if you're using the octo/cart
capability then we add the same key to that as well. The value will look like this:
In the response we provide publicKey
value which you can use with Bridgepay's TokenPay.js SDK described in the documentation here:
On the client side, the payment page should look something like this:
The value of result.token
which in this example we set on the hidden input field in the form. You must then send this to Ventrata using either of the confirmation endpoints (depending if you're using the octo/cart
capability):
POST /bookings/:uuid/confirm
POST /orders/:orderId/confirm
Ventrata will then use the card token to authorise and capture the payment amount on the order and confirm the booking.
Stripe Gateway
We add a cardPayment
key to the booking object, but if you're using the octo/cart
capability then we add the same key to that as well. The value will look like this:
In the response we give some parameters under cardPayment which includes a stripe payment intent. You should follow the Stripe documentation from this section:
https://stripe.com/docs/payments/accept-a-payment?platform=web&ui=elements
Check the Stripe documentation for more complete examples, but here is an example:
Once the payment is confirmed you can perform either:
POST /bookings/:uuid/confirm
POST /orders/:orderId/confirm
The second endpoint is if you're using the octo/cart
capability. You then must include the payment intent id in the request body. If you prefer to use a Stripe payment method id instead that's also possible. Both examples are given below:
Setup Intent
If you do not want to take a payment, but you do want to save an active card against the order which can be charged in future without the customer being present, you can use the setup intent functionality provided by the Stripe gateway.
In the booking/order response, next to the paymentIntent
object will be a new field called setupIntent
which will look like this:
The response object will look very similar to the paymentIntent
object except it won't contain the amount
and currency
fields because unlike a paymentIntent we're not actually charging the card, we're just collecting the details to be used later. This can be helpful for a "Buy Now, Pay Later" scenario.
To collect the card details from the customer, follow Stripe's guide here: https://stripe.com/docs/payments/save-and-reuse
A simple example using Stripe's card element would be:
Once the card setup is confirmed you can perform either:
POST /bookings/:uuid/confirm
POST /orders/:orderId/confirm
The second endpoint is if you're using the octo/cart
capability. You then must include the setup intent id in the request body. If you prefer to use a Stripe payment method id instead that's also possible. Both examples are given below:
Note if you use the payment method route we include "amount": 0
in the body. This is critical because it tells the system to use set the payment method up to be used in future rather than charging it right now. This isn't necessary for the Setup Intent method.
External Gateway
The external gateway is the simplest and isn't actually a gateway at all. It allows you to register a virtual card payment which might have been taken on another gateway not supported by Ventrata.
We add a cardPayment
key to the booking object, but if you're using the octo/cart
capability then we add the same key to that as well. The value will look like this:
Once the payment is confirmed you can perform either:
POST /bookings/:uuid/confirm
POST /orders/:orderId/confirm
The second endpoint is if you're using the octo/cart
capability. You can then optionally include notes
in the external field which will can record an external payment reference which might be useful for backend reconciliation later. For example:
Last updated