Cost+Docs

Java / Kotlin

Offisiell Kotlin/Java SDK for Cost+ betalingsgateway

Offisiell Kotlin SDK for Cost+ betalingsgateway, fullt kompatibel med Java. Forenkler HPP (Hosted Payment Page) videresendingsflyten, HMAC-signering av innhold og webhook-verifisering.

Funksjoner

  • Kotlin-først, Java-vennlig — data classes, coroutines, null-sikkerhet; fullt brukbar fra Java
  • kotlinx.serialization — ingen Gson/Jackson-avhengighet; automatisk snake_case/camelCase-kartlegging
  • HMAC-SHA256 signaturgenerering og konstanttids-verifisering
  • Webhook-parsing + API-basert ordreverifisering
  • Suspend-funksjoner for ikke-blokkerende IO via Kotlin coroutines
  • Injiserbar HttpClient for enkel testing med mock-transporter
  • Målretter Java 17+

Krav

Installasjon

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>

Hurtigstart (Kotlin)

1. Initialiser klienten

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

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

2. Opprett en betaling og videresend til 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. Håndter webhooken

// 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
}

Hurtigstart (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);
    }
}

API-referanse

NoPaynClient(config, httpClient?)

ParameterTypePåkrevdStandard
config.apiKeyStringJa
config.merchantIdStringJa
config.baseUrlStringNeihttps://api.nopayn.co.uk
httpClientjava.net.http.HttpClientNeiStandard klient

client.createOrder(params): Order (suspend)

Oppretter en ordre via POST /v1/orders/.

ParameterTypePåkrevdBeskrivelse
amountIntJaBeløp i minste valutaenhet (øre/cent)
currencyStringJaISO 4217-kode (EUR, GBP, USD, NOK, SEK)
merchantOrderIdString?NeiDin interne ordrereferanse
descriptionString?NeiOrdrebeskrivelse
returnUrlString?NeiVideresending etter vellykket betaling
failureUrlString?NeiVideresending ved avbrudd/utløp/feil
webhookUrlString?NeiAsynkrone statusendringsvarsler
localeString?NeiHPP-språk (en-GB, de-DE, nl-NL, osv.)
paymentMethodsList<String>?NeiFiltrer HPP-metoder
expirationPeriodString?NeiISO 8601-varighet (PT30M)

Tilgjengelige betalingsmetoder: credit-card, apple-pay, google-pay, vipps-mobilepay

client.getOrder(orderId): Order (suspend)

Henter ordredetaljer via GET /v1/orders/{id}/.

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

Utsteder en full eller delvis refusjon via POST /v1/orders/{id}/refunds/.

client.generatePaymentUrl(params): PaymentUrlResult (suspend)

Bekvemmelighetsmetode som oppretter en ordre og returnerer:

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

Genererer en HMAC-SHA256 hex-signatur. Den kanoniske meldingen er $amount:$currency:$orderId, signert med API-nøkkelen.

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

Konstanttids-verifisering av en HMAC-SHA256-signatur.

client.verifyWebhook(rawBody): VerifiedWebhook (suspend)

Parser webhook-kroppen, kaller deretter GET /v1/orders/{id}/ for å verifisere faktisk status.

Frittstående HMAC-verktøy

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)

Fra Java:

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

Feilhåndtering

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
}

Ordrestatuser

StatusEndelig?Beskrivelse
newNeiOrdre opprettet
processingNeiBetaling pågår
completedJaBetaling vellykket — lever varene
cancelledJaBetaling avbrutt av kunden
expiredJaBetalingslenken utløp
errorJaTeknisk feil

Beste praksis for webhooks

  1. Verifiser alltid via API-et — webhook-innholdet inneholder kun ordre-ID-en, aldri statusen. SDK-ens verifyWebhook() gjør dette automatisk.
  2. Returner HTTP 200 for å bekrefte mottak. Enhver annen kode utløser opptil 10 nye forsøk (2 minutters mellomrom).
  3. Implementer en reservepoller — for ordrer eldre enn 10 minutter som ikke har nådd en endelig status, poll getOrder() som sikkerhetsnett.
  4. Vær idempotent — du kan motta samme webhook flere ganger.

Testkort

Bruk disse kortene i Cost+ testmodus (sandbox-nettsted):

KortNummerMerknader
Visa (vellykket)4111 1111 1111 1111Valgfritt CVV
Mastercard (vellykket)5544 3300 0003 7Valgfritt CVV
Visa (avvist)4111 1111 1111 1105Do Not Honor
Visa (utilstrekkelige midler)4111 1111 1111 1151Insufficient Funds

Bruk en hvilken som helst fremtidig utløpsdato og en hvilken som helst 3-sifret CVC.

Demoapp

En Docker-basert demoapp (Ktor) er inkludert i GitHub-repositoriet for testing av den fullstendige betalingsflyten.

Kundestøtte

Trenger du hjelp? Kontakt kundestøtteteamet vårt på support@costplus.io.

On this page