Payments - Usage Examples
Last Updated: 2026-07-08
Endpoints below use the root-level hyphenated routes (/payment-methods/, /payment-processors/, /refunds/) where they exist, and the app-prefixed routes (/payments/payments/, /payments/terminal/..., /payments/confirm/) where they don't. See Views for the full URL grounding, both route families are live.
Authentication
# Step 1: Obtain token
curl -s -X POST https://api.djanity.com/auth/login/ \
-H "Content-Type: application/json" \
-d '{"username": "[email protected]", "password": "..."}'
# Returns: {"access": "<jwt>", "refresh": "<jwt>"}
# Step 2: All subsequent requests use:
# -H "Authorization: Bearer <token>"
Payment Methods
List payment methods for a store
curl -s "https://api.djanity.com/payment-methods/by_store/?store_id=<django-store-uuid>"
Response:
{
"store_id": "<django-store-uuid>",
"available_methods": [
{
"id": "pm-a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"sanity_id": "pm-cash",
"name": "Cash",
"method_type": "cash",
"is_active": true,
"is_pos_available": true,
"minimum_amount": "0.01",
"maximum_amount": null,
"display_order": 1,
"configuration": {},
"processor": null
},
{
"id": "pm-b2c3d4e5-f6a7-8901-bcde-f12345678901",
"sanity_id": "pm-visa-mastercard",
"name": "Visa/Mastercard",
"method_type": "credit_card",
"is_active": true,
"is_pos_available": true,
"minimum_amount": "0.50",
"maximum_amount": null,
"display_order": 2,
"processor": {
"id": "processor-uuid",
"name": "Stripe Production",
"processor_type": "stripe",
"processing_fee_percentage": "2.90",
"processing_fee_fixed": "0.30"
}
}
],
"count": 2
}
processor.configuration is never included in this response, only fee and display metadata needed by POS clients.
Terminal Payments
Request a connection token (processor-agnostic)
curl -s -X POST https://api.djanity.com/payments/terminal/connection-token/ \
-H "Content-Type: application/json" \
-d '{"processor_type": "stripe"}'
Response:
{
"secret": "pctx_1OqXxX2eZvKYlo2C8nKLpQXY",
"processor_type": "stripe"
}
Create a terminal payment session
curl -s -X POST https://api.djanity.com/payments/terminal/create-payment/ \
-H "Content-Type: application/json" \
-d '{
"processor_type": "stripe",
"amount": 4318,
"currency": "usd"
}'
Response:
{
"id": "pi_1OqXxX2eZvKYlo2CAbCdEfGh",
"client_secret": "pi_1OqXxX2eZvKYlo2CAbCdEfGh_secret_...",
"amount": 4318,
"currency": "usd",
"status": "requires_payment_method"
}
Confirm a payment after a 3DS challenge
curl -s -X POST https://api.djanity.com/payments/confirm/ \
-H "Content-Type: application/json" \
-d '{"payment_intent_id": "pi_1OqXxX2eZvKYlo2CAbCdEfGh"}'
Response (success):
{"confirmed": true, "transaction_id": "223e4567-e89b-12d3-a456-426614174001"}
Response (failure):
{"confirmed": false, "error": "Payment failed. Status: requires_payment_method"}
This endpoint is authorized by matching the caller's web session to the CheckoutSession behind the referenced payment, not by a bearer token, it is safe to call unauthenticated because ownership is verified server-side against local DB state.
Refunds
RefundService - tuple unpacking
RefundService.process_refund always returns a 3-tuple. Call sites must unpack all three values:
from nextango.apps.payments.services import RefundService
from decimal import Decimal
# Success path
success, refund, message = RefundService.process_refund(
payment_id=payment_uuid,
amount=Decimal("43.18"),
reason="Customer returned item"
)
if success:
# refund is a Refund instance with status='succeeded'
print(f"Refund {refund.refund_id} processed: {message}")
else:
if refund is not None:
# A failed Refund record was persisted (status='failed')
# This happens when payment.payment_method is None
print(f"Refund {refund.refund_id} created but failed: {message}")
else:
# Validation error or unexpected exception, no Refund record created
print(f"Refund rejected: {message}")
Key behavior: when payment.payment_method is None, a Refund row is written to the database with status='failed' and returned as the second element of the tuple. Callers should check refund is not None before accessing refund.refund_id.
Process a refund
curl -s -X POST https://api.djanity.com/payments/payments/pay-uuid-here/process_refund/ \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"amount": "43.18",
"reason": "Customer returned item, defective product"
}'
Response (201 Created):
{
"id": "ref-uuid-here",
"refund_id": "REF-20260708-A1B2C3D4",
"payment": "pay-uuid-here",
"amount": "43.18",
"reason": "Customer returned item, defective product",
"status": "pending",
"processor_refund_id": null,
"created_at": "2026-07-08T15:00:00Z"
}
This is the recommended path over POST /refunds/ directly, process_refund includes the cumulative-refund-amount check against existing refunds on the same payment.