Python
Officiele Python SDK voor de Cost+ betaalgateway
Officiele Python SDK voor de Cost+ betaalgateway. Vereenvoudigt de HPP (Hosted Payment Page) doorverwijzingsflow, HMAC-payloadondertekening en webhookverificatie.
Kenmerken
- Minimale afhankelijkheden — alleen
requests - Volledige type hints en frozen dataclass-retourtypen
- HMAC-SHA256-handtekeninggeneratie en constant-time verificatie
- Webhook-parsing + API-gebaseerde bestellingsverificatie
- Getest op Python 3.10, 3.11 en 3.12
Vereisten
- Python 3.10 of hoger
- Een Cost+ handelaarsaccount — dashboard.costplus.io
Installatie
pip install nopayn-sdkSnelstart
1. De client initialiseren
from nopayn import NoPaynClient
client = NoPaynClient(
api_key="your-api-key",
merchant_id="your-project",
)2. Een betaling aanmaken en doorverwijzen naar de HPP
result = client.generate_payment_url(
amount=1295, # €12.95 in cents
currency="EUR",
merchant_order_id="ORDER-001",
description="Premium Widget",
return_url="https://shop.example.com/success",
failure_url="https://shop.example.com/failure",
webhook_url="https://shop.example.com/webhook",
locale="en-GB",
expiration_period="PT30M",
)
# Redirect the customer
# result.order_url → HPP (customer picks payment method)
# result.payment_url → direct link to the first transaction's payment method
# result.signature → HMAC-SHA256 for verification
# result.order_id → NoPayn order UUID3. De webhook afhandelen (Flask-voorbeeld)
@app.route("/webhook", methods=["POST"])
def webhook():
verified = client.verify_webhook(request.get_data(as_text=True))
print(verified.order.status) # 'completed', 'cancelled', etc.
print(verified.is_final) # True when the order won't change
if verified.order.status == "completed":
# Fulfil the order
pass
return "", 200API-referentie
NoPaynClient(api_key, merchant_id, base_url?)
| Parameter | Type | Vereist | Standaard |
|---|---|---|---|
api_key | str | Ja | — |
merchant_id | str | Ja | — |
base_url | str | Nee | https://api.nopayn.co.uk |
client.create_order(**kwargs) -> Order
Maakt een bestelling aan via POST /v1/orders/.
| Parameter | Type | Vereist | Beschrijving |
|---|---|---|---|
amount | int | Ja | Bedrag in kleinste valuta-eenheid (centen) |
currency | str | Ja | ISO 4217-code (EUR, GBP, USD, NOK, SEK) |
merchant_order_id | str | Nee | Uw interne bestellingsreferentie |
description | str | Nee | Bestellingsbeschrijving |
return_url | str | Nee | Doorverwijzing na geslaagde betaling |
failure_url | str | Nee | Doorverwijzing bij annulering/verloop/fout |
webhook_url | str | Nee | Asynchrone statuswijzigingsmeldingen |
locale | str | Nee | HPP-taal (en-GB, de-DE, nl-NL, enz.) |
payment_methods | list[str] | Nee | HPP-methoden filteren |
expiration_period | str | Nee | ISO 8601-duur (PT30M) |
Beschikbare betaalmethoden: credit-card, apple-pay, google-pay, vipps-mobilepay
client.get_order(order_id) -> Order
Haalt bestellingsdetails op via GET /v1/orders/{id}/.
client.create_refund(order_id, amount, description?) -> Refund
Voert een volledige of gedeeltelijke terugbetaling uit via POST /v1/orders/{id}/refunds/.
client.generate_payment_url(**kwargs) -> PaymentUrlResult
Hulpmethode die een bestelling aanmaakt en retourneert:
PaymentUrlResult(
order_id="...", # NoPayn order UUID
order_url="...", # HPP URL
payment_url="...", # Direct payment URL (first transaction)
signature="...", # HMAC-SHA256 of amount:currency:order_id
order=Order(...), # Full order object
)client.generate_signature(amount, currency, order_id) -> str
Genereert een HMAC-SHA256 hex-handtekening.
client.verify_signature(amount, currency, order_id, signature) -> bool
Constant-time verificatie van een HMAC-SHA256-handtekening.
client.verify_webhook(raw_body) -> VerifiedWebhook
Parst de webhook-body en roept vervolgens GET /v1/orders/{id}/ aan om de werkelijke status te verifieren.
Standalone HMAC-hulpmiddelen
from nopayn import generate_signature, verify_signature
sig = generate_signature("your-api-key", 1295, "EUR", "order-uuid")
ok = verify_signature("your-api-key", 1295, "EUR", "order-uuid", sig)Datatypen
Alle API-respons worden geretourneerd als frozen dataclasses:
| Klasse | Velden |
|---|---|
Order | id, amount, currency, status, created, modified, transactions, description, merchant_order_id, return_url, failure_url, order_url, completed |
Transaction | id, amount, currency, status, created, modified, payment_method, payment_url, expiration_period |
Refund | id, amount, status |
PaymentUrlResult | order_id, order_url, payment_url, signature, order |
VerifiedWebhook | order_id, order, is_final |
Foutafhandeling
from nopayn import ApiError, NoPaynError, WebhookError
try:
client.create_order(amount=100, currency="EUR")
except ApiError as exc:
print(exc.status_code) # 401, 400, etc.
print(exc.error_body) # Raw API error response
except NoPaynError as exc:
print(exc) # Network or parsing errorBestellingsstatussen
| Status | Definitief? | Beschrijving |
|---|---|---|
new | Nee | Bestelling aangemaakt |
processing | Nee | Betaling wordt verwerkt |
completed | Ja | Betaling geslaagd — lever de goederen |
cancelled | Ja | Betaling geannuleerd door klant |
expired | Ja | Betaallink verlopen |
error | Ja | Technische storing |
Best practices voor webhooks
- Verifieer altijd via de API — de webhook-payload bevat alleen het bestelling-ID, nooit de status. De
verify_webhook()van de SDK doet dit automatisch. - Retourneer HTTP 200 om de ontvangst te bevestigen. Elke andere code triggert tot 10 herhaalpogingen (2 minuten tussenpozen).
- Implementeer een backup-poller — voor bestellingen ouder dan 10 minuten die nog geen definitieve status hebben bereikt, poll
get_order()als vangnet. - Wees idempotent — u kunt dezelfde webhook meerdere keren ontvangen.
Testkaarten
Gebruik deze kaarten in Cost+ testmodus (sandbox-website):
| Kaart | Nummer | Opmerkingen |
|---|---|---|
| Visa (geslaagd) | 4111 1111 1111 1111 | Willekeurige CVV |
| Mastercard (geslaagd) | 5544 3300 0003 7 | Willekeurige CVV |
| Visa (geweigerd) | 4111 1111 1111 1105 | Do Not Honor |
| Visa (onvoldoende saldo) | 4111 1111 1111 1151 | Insufficient Funds |
Gebruik een willekeurige toekomstige vervaldatum en een willekeurige 3-cijferige CVC.
Demo-app
Een op Flask gebaseerde demo-app is opgenomen in de GitHub-repository om de volledige betalingsflow te testen.
Ondersteuning
Hulp nodig? Neem contact op met ons supportteam via support@costplus.io.