Cost+Docs

Java / Kotlin

SDK ufficiale Kotlin/Java per il gateway di pagamento Cost+

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

Caratteristiche

  • Kotlin-first, compatibile con Java — data class, coroutine, null safety; completamente utilizzabile da Java
  • kotlinx.serialization — nessuna dipendenza Gson/Jackson; mappatura automatica snake_case/camelCase
  • Generazione firma HMAC-SHA256 e verifica a tempo costante
  • Analisi webhook + verifica dell'ordine basata su API
  • Funzioni suspend per IO non bloccante tramite coroutine Kotlin
  • HttpClient iniettabile per test facili con transport mock
  • Target Java 17+

Requisiti

Installazione

Gradle (Kotlin DSL)

dependencies {
    implementation("io.nopayn:nopayn-sdk:1.0.0")
}

Gradle (Groovy)

dependencies {
    implementation 'io.nopayn:nopayn-sdk:1.0.0'
}

Maven

<dependency>
    <groupId>io.nopayn</groupId>
    <artifactId>nopayn-sdk</artifactId>
    <version>1.0.0</version>
</dependency>

Guida Rapida (Kotlin)

1. Inizializza il Client

import io.nopayn.*
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {
    val nopayn = NoPaynClient(
        NoPaynConfig(
            apiKey = "your-api-key",
            merchantId = "your-project",
        )
    )
}

2. Crea un Pagamento e Reindirizza all'HPP

val result = nopayn.generatePaymentUrl(
    CreateOrderParams(
        amount = 1295,            // €12.95 in cents
        currency = "EUR",
        merchantOrderId = "ORDER-001",
        description = "Premium Widget",
        returnUrl = "https://shop.example.com/success",
        failureUrl = "https://shop.example.com/failure",
        webhookUrl = "https://shop.example.com/webhook",
        locale = "en-GB",
        expirationPeriod = "PT30M",
    )
)

println(result.orderUrl)    // HPP URL
println(result.paymentUrl)  // Direct payment method URL
println(result.signature)   // HMAC-SHA256 signature

3. Gestisci il Webhook

// In your HTTP handler (Ktor, Spring, etc.)
val rawBody: String = request.body()
val verified = nopayn.verifyWebhook(rawBody)

println(verified.order.status)  // "completed", "cancelled", etc.
println(verified.isFinal)       // true when the order won't change

if (verified.order.status == "completed") {
    // Fulfil the order
}

Guida Rapida (Java)

import io.nopayn.*;
import kotlinx.coroutines.BuildersKt;
import kotlinx.coroutines.Dispatchers;

public class Example {
    public static void main(String[] args) throws Exception {
        NoPaynClient client = new NoPaynClient(
            new NoPaynConfig("your-api-key", "your-project", "https://api.nopayn.co.uk")
        );

        Order order = BuildersKt.runBlocking(
            Dispatchers.getIO(),
            (scope, continuation) -> client.createOrder(
                new CreateOrderParams(
                    1295, "EUR", "ORDER-001", "Premium Widget",
                    "https://shop.example.com/success",
                    "https://shop.example.com/failure",
                    "https://shop.example.com/webhook",
                    "en-GB", null, "PT30M"
                ),
                continuation
            )
        );

        System.out.println("Order ID: " + order.getId());
        System.out.println("Order URL: " + order.getOrderUrl());

        // Signature utilities work synchronously
        String sig = client.generateSignature(1295, "EUR", order.getId());
        boolean valid = client.verifySignature(1295, "EUR", order.getId(), sig);
    }
}

Riferimento API

NoPaynClient(config, httpClient?)

ParametroTipoObbligatorioPredefinito
config.apiKeyString
config.merchantIdString
config.baseUrlStringNohttps://api.nopayn.co.uk
httpClientjava.net.http.HttpClientNoClient predefinito

client.createOrder(params): Order (suspend)

Crea un ordine tramite POST /v1/orders/.

ParametroTipoObbligatorioDescrizione
amountIntImporto nell'unità valutaria più piccola (centesimi)
currencyStringCodice ISO 4217 (EUR, GBP, USD, NOK, SEK)
merchantOrderIdString?NoIl tuo riferimento interno dell'ordine
descriptionString?NoDescrizione dell'ordine
returnUrlString?NoReindirizzamento dopo pagamento riuscito
failureUrlString?NoReindirizzamento in caso di annullamento/scadenza/errore
webhookUrlString?NoNotifiche asincrone di cambio stato
localeString?NoLingua HPP (en-GB, de-DE, nl-NL, ecc.)
paymentMethodsList<String>?NoFiltra i metodi HPP
expirationPeriodString?NoDurata ISO 8601 (PT30M)

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

client.getOrder(orderId): Order (suspend)

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

client.createRefund(orderId, amount, description?): Refund (suspend)

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

client.generatePaymentUrl(params): PaymentUrlResult (suspend)

Metodo di convenienza che crea un ordine e restituisce:

PaymentUrlResult(
    orderId: String,     // NoPayn order UUID
    orderUrl: String,    // HPP URL
    paymentUrl: String?, // Direct payment URL (first transaction)
    signature: String,   // HMAC-SHA256 of amount:currency:orderId
    order: Order,        // Full order object
)

client.generateSignature(amount, currency, orderId): String

Genera una firma HMAC-SHA256 esadecimale. Il messaggio canonico è $amount:$currency:$orderId, firmato con la chiave API.

client.verifySignature(amount, currency, orderId, signature): Boolean

Verifica a tempo costante di una firma HMAC-SHA256.

client.verifyWebhook(rawBody): VerifiedWebhook (suspend)

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

Utility HMAC Standalone

import io.nopayn.NoPaynSignature

val sig = NoPaynSignature.generate("your-api-key", 1295, "EUR", "order-uuid")
val ok  = NoPaynSignature.verify("your-api-key", 1295, "EUR", "order-uuid", sig)

Da Java:

String sig = NoPaynSignature.generate("your-api-key", 1295, "EUR", "order-uuid");
boolean ok = NoPaynSignature.verify("your-api-key", 1295, "EUR", "order-uuid", sig);

Gestione degli Errori

import io.nopayn.*

try {
    nopayn.createOrder(CreateOrderParams(amount = 100, currency = "EUR"))
} catch (e: ApiException) {
    println(e.statusCode)  // 401, 400, etc.
    println(e.errorBody)   // Raw API error response
} catch (e: NoPaynException) {
    println(e.message)     // 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 verifyWebhook() 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 getOrder() 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 Docker (Ktor) è 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