Skip to main content

Payments API

Stripe-powered payment processing for EV charging sessions and parking bookings.

Status: Production Ready

Fully integrated with Stripe for secure payment processing.

Overview​

The Payments API enables secure payment processing through Stripe integration. Create payment intents for bookings, handle webhooks, and manage transaction status.

Base URL: https://api.rollyy.com/v1/payments

Authentication​

All payment endpoints require API key authentication via the X-API-Key header.

curl -H "X-API-Key: test-api-key-123" \
-H "Content-Type: application/json" \
https://api.rollyy.com/v1/payments/create-intent

Test API Key: test-api-key-123

Endpoints​

Create Payment Intent​

Create a Stripe Payment Intent for a booking.

Endpoint: POST /v1/payments/create-intent

Request Body:

FieldTypeRequiredDescription
amountfloatYesPayment amount in USD (e.g., 3.50)
currencystringNoCurrency code (default: "usd")
booking_idUUIDYesID of the booking to charge for

Example Request:

curl -X POST https://api.rollyy.com/v1/payments/create-intent \
-H "Content-Type: application/json" \
-H "X-API-Key: test-api-key-123" \
-d '{
"amount": 3.50,
"currency": "usd",
"booking_id": "6db74bfd-bfba-47a9-86e5-2304af3a6e40"
}'

Response (200 OK):

{
"client_secret": "pi_3Sxb...secret_Vxvq...",
"payment_intent_id": "pi_3SxbzLQ1qtFrV1Tp16Yftm36"
}

Response Fields:

  • client_secret - Secret to complete payment on client side with Stripe.js
  • payment_intent_id - Stripe Payment Intent ID for tracking

Stripe Webhook​

Receive webhook events from Stripe when payment status changes.

Endpoint: POST /v1/payments/webhook

Webhook Events:

  • payment_intent.succeeded - Payment completed successfully
  • payment_intent.payment_failed - Payment failed

Configure in Stripe Dashboard:

https://api.rollyy.com/v1/payments/webhook

Complete Payment Flow​

Step 1: Create a Booking​

First, create a booking for the charging session:

POST /v1/bookings
{
"asset_id": "550e8400-e29b-41d4-a716-446655440000",
"asset_type": "charging_station",
"user_id": "650e8400-e29b-41d4-a716-446655440001",
"start_time": "2026-02-05T23:00:00Z",
"end_time": "2026-02-05T23:30:00Z"
}

Step 2: Create Payment Intent​

Use the booking ID to create a payment:

POST /v1/payments/create-intent
{
"amount": 4.50,
"currency": "usd",
"booking_id": "{booking_id_from_step_1}"
}

Step 3: Complete Payment (Client Side)​

Use the returned client_secret with Stripe.js:

const stripe = Stripe('pk_test_...');
const {error} = await stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: cardElement,
billing_details: {name: 'Customer Name'}
}
});

Step 4: Webhook Updates Booking​

When payment succeeds, Stripe sends webhook to update booking payment_status to "completed".

Testing​

Test Amounts

Use small amounts ($2-5) for testing. Stripe may flag large test amounts.

Test Cards​

Card NumberScenario
4242 4242 4242 4242✅ Successful payment
4000 0000 0000 0002❌ Card declined
4000 0025 0000 3155🔐 Requires authentication (3D Secure)

Expiry: Any future date
CVC: Any 3 digits

Error Responses​

401 Unauthorized​

{"detail": "Invalid API key"}

404 Not Found​

{"detail": "Booking not found"}

400 Bad Request​

{"detail": "Stripe error message"}

Integration Examples​

JavaScript/TypeScript​

const response = await fetch(
'https://api.rollyy.com/v1/payments/create-intent',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'test-api-key-123'
},
body: JSON.stringify({
amount: 3.50,
currency: 'usd',
booking_id: 'your-booking-id'
})
}
);

const {client_secret, payment_intent_id} = await response.json();

// Complete payment with Stripe.js
const stripe = Stripe('pk_test_...');
const result = await stripe.confirmCardPayment(client_secret, {
payment_method: {
card: cardElement,
billing_details: {name: 'John Doe'}
}
});

if (result.error) {
console.error('Payment failed:', result.error.message);
} else {
console.log('Payment succeeded:', result.paymentIntent.id);
}

Python​

import requests

response = requests.post(
'https://api.rollyy.com/v1/payments/create-intent',
headers={'X-API-Key': 'test-api-key-123'},
json={
'amount': 3.50,
'currency': 'usd',
'booking_id': 'your-booking-id'
}
)

data = response.json()
client_secret = data['client_secret']
payment_intent_id = data['payment_intent_id']

cURL​

curl -X POST https://api.rollyy.com/v1/payments/create-intent \
-H "Content-Type: application/json" \
-H "X-API-Key: test-api-key-123" \
-d '{
"amount": 3.50,
"currency": "usd",
"booking_id": "6db74bfd-bfba-47a9-86e5-2304af3a6e40"
}'

Best Practices​

Security​

  • Never expose your API key in client-side code
  • Always create payment intents from your backend
  • Verify webhook signatures in production

Idempotency​

  • Payment intents are idempotent
  • Creating multiple intents for the same booking is safe
  • Stripe handles duplicate requests automatically

Resources​