Cost+Docs

Python

SDK ufficiale Python per il gateway di pagamento Cost+

SDK ufficiale Python per il gateway di pagamento Cost+. Semplifica il flusso di reindirizzamento HPP (Pagina di Pagamento Ospitata), la firma dei payload HMAC e la verifica dei webhook.

Caratteristiche

  • Dipendenze minime — solo requests
  • Type hint completi e tipi di ritorno dataclass frozen
  • Generazione firma HMAC-SHA256 e verifica a tempo costante
  • Analisi webhook + verifica dell'ordine basata su API
  • Testato su Python 3.10, 3.11 e 3.12

Requisiti

Installazione

pip install nopayn-sdk

Guida Rapida

1. Inizializza il Client

from nopayn import NoPaynClient

client = NoPaynClient(
    api_key="your-api-key",
    merchant_id="your-project",
)

2. Crea un Pagamento e Reindirizza all'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 UUID

3. Gestisci il Webhook (Esempio Flask)

@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 "", 200

Riferimento API

NoPaynClient(api_key, merchant_id, base_url?)

ParametroTipoObbligatorioPredefinito
api_keystr
merchant_idstr
base_urlstrNohttps://api.nopayn.co.uk

client.create_order(**kwargs) -> Order

Crea un ordine tramite POST /v1/orders/.

ParametroTipoObbligatorioDescrizione
amountintImporto nell'unità valutaria più piccola (centesimi)
currencystrCodice ISO 4217 (EUR, GBP, USD, NOK, SEK)
merchant_order_idstrNoIl tuo riferimento interno dell'ordine
descriptionstrNoDescrizione dell'ordine
return_urlstrNoReindirizzamento dopo pagamento riuscito
failure_urlstrNoReindirizzamento in caso di annullamento/scadenza/errore
webhook_urlstrNoNotifiche asincrone di cambio stato
localestrNoLingua HPP (en-GB, de-DE, nl-NL, ecc.)
payment_methodslist[str]NoFiltra i metodi HPP
expiration_periodstrNoDurata ISO 8601 (PT30M)

Metodi di pagamento disponibili: credit-card, apple-pay, google-pay, vipps-mobilepay

client.get_order(order_id) -> Order

Recupera i dettagli dell'ordine tramite GET /v1/orders/{id}/.

client.create_refund(order_id, amount, description?) -> Refund

Emette un rimborso totale o parziale tramite POST /v1/orders/{id}/refunds/.

client.generate_payment_url(**kwargs) -> PaymentUrlResult

Metodo di convenienza che crea un ordine e restituisce:

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

Genera una firma HMAC-SHA256 esadecimale.

client.verify_signature(amount, currency, order_id, signature) -> bool

Verifica a tempo costante di una firma HMAC-SHA256.

client.verify_webhook(raw_body) -> VerifiedWebhook

Analizza il corpo del webhook, poi chiama GET /v1/orders/{id}/ per verificare lo stato effettivo.

Utility HMAC Standalone

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)

Tipi di Dati

Tutte le risposte API vengono restituite come dataclass frozen:

ClasseCampi
Orderid, amount, currency, status, created, modified, transactions, description, merchant_order_id, return_url, failure_url, order_url, completed
Transactionid, amount, currency, status, created, modified, payment_method, payment_url, expiration_period
Refundid, amount, status
PaymentUrlResultorder_id, order_url, payment_url, signature, order
VerifiedWebhookorder_id, order, is_final

Gestione degli Errori

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 error

Stati dell'Ordine

StatoFinale?Descrizione
newNoOrdine creato
processingNoPagamento in corso
completedPagamento riuscito — consegna la merce
cancelledPagamento annullato dal cliente
expiredLink di pagamento scaduto
errorErrore tecnico

Best Practice per i Webhook

  1. Verifica sempre tramite API — il payload del webhook contiene solo l'ID dell'ordine, mai lo stato. Il metodo verify_webhook() dell'SDK lo fa automaticamente.
  2. Restituisci HTTP 200 per confermare la ricezione. Qualsiasi altro codice attiva fino a 10 tentativi (ogni 2 minuti).
  3. Implementa un poller di backup — per gli ordini più vecchi di 10 minuti che non hanno raggiunto uno stato finale, interroga get_order() come rete di sicurezza.
  4. Sii idempotente — potresti ricevere lo stesso webhook più volte.

Carte di Test

Usa queste carte in modalità test Cost+ (sito web sandbox):

CartaNumeroNote
Visa (successo)4111 1111 1111 1111Qualsiasi CVV
Mastercard (successo)5544 3300 0003 7Qualsiasi CVV
Visa (rifiutata)4111 1111 1111 1105Do Not Honor
Visa (fondi insufficienti)4111 1111 1111 1151Insufficient Funds

Usa qualsiasi data di scadenza futura e qualsiasi CVC a 3 cifre.

App Demo

Un'app demo basata su Flask è inclusa nel repository GitHub per testare il flusso di pagamento completo.

Supporto

Hai bisogno di aiuto? Contatta il nostro team di supporto a support@costplus.io.

On this page