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