Java / Kotlin
Oficiální Kotlin/Java SDK pro platební bránu Cost+
Oficiální Kotlin SDK pro platební bránu Cost+, plně interoperabilní s Javou. Zjednodušuje tok přesměrování HPP (Hosted Payment Page), HMAC podepisování payloadu a ověřování webhooků.
Funkce
- Kotlin-first, přátelský k Javě — data classes, coroutines, null safety; plně použitelné z Javy
- kotlinx.serialization — žádná závislost na Gson/Jackson; automatické mapování snake_case/camelCase
- Generování podpisů HMAC-SHA256 a ověřování s konstantním časem
- Parsování webhooků + ověřování objednávek přes API
- Suspend funkce pro neblokující IO přes Kotlin coroutines
- Injektovatelný
HttpClientpro snadné testování s mock transports - Cílí na Java 17+
Požadavky
- JDK 17 nebo novější
- Obchodní účet Cost+ — dashboard.costplus.io
Instalace
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>Rychlý start (Kotlin)
1. Inicializace klienta
import io.nopayn.*
import kotlinx.coroutines.runBlocking
fun main() = runBlocking {
val nopayn = NoPaynClient(
NoPaynConfig(
apiKey = "your-api-key",
merchantId = "your-project",
)
)
}2. Vytvoření platby a přesměrování na 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 signature3. Zpracování webhooku
// 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
}Rychlý start (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 reference
NoPaynClient(config, httpClient?)
| Parametr | Typ | Povinné | Výchozí |
|---|---|---|---|
config.apiKey | String | Ano | — |
config.merchantId | String | Ano | — |
config.baseUrl | String | Ne | https://api.nopayn.co.uk |
httpClient | java.net.http.HttpClient | Ne | Výchozí klient |
client.createOrder(params): Order (suspend)
Vytvoří objednávku přes POST /v1/orders/.
| Parametr | Typ | Povinné | Popis |
|---|---|---|---|
amount | Int | Ano | Částka v nejmenší měnové jednotce (centy) |
currency | String | Ano | ISO 4217 kód (EUR, GBP, USD, NOK, SEK) |
merchantOrderId | String? | Ne | Vaše interní reference objednávky |
description | String? | Ne | Popis objednávky |
returnUrl | String? | Ne | Přesměrování po úspěšné platbě |
failureUrl | String? | Ne | Přesměrování při zrušení/vypršení/chybě |
webhookUrl | String? | Ne | Asynchronní notifikace o změně stavu |
locale | String? | Ne | Jazyk HPP (en-GB, de-DE, nl-NL atd.) |
paymentMethods | List<String>? | Ne | Filtr metod HPP |
expirationPeriod | String? | Ne | ISO 8601 doba trvání (PT30M) |
Dostupné platební metody: credit-card, apple-pay, google-pay, vipps-mobilepay
client.getOrder(orderId): Order (suspend)
Načte detaily objednávky přes GET /v1/orders/{id}/.
client.createRefund(orderId, amount, description?): Refund (suspend)
Provede úplnou nebo částečnou refundaci přes POST /v1/orders/{id}/refunds/.
client.generatePaymentUrl(params): PaymentUrlResult (suspend)
Pohodlná metoda, která vytvoří objednávku a vrátí:
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
Generuje HMAC-SHA256 hex podpis. Kanonická zpráva je $amount:$currency:$orderId, podepsaná API klíčem.
client.verifySignature(amount, currency, orderId, signature): Boolean
Ověření HMAC-SHA256 podpisu s konstantním časem.
client.verifyWebhook(rawBody): VerifiedWebhook (suspend)
Parsuje tělo webhooku a poté zavolá GET /v1/orders/{id}/ pro ověření skutečného stavu.
Samostatné HMAC utility
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)Z Javy:
String sig = NoPaynSignature.generate("your-api-key", 1295, "EUR", "order-uuid");
boolean ok = NoPaynSignature.verify("your-api-key", 1295, "EUR", "order-uuid", sig);Zpracování chyb
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
}Stavy objednávek
| Stav | Konečný? | Popis |
|---|---|---|
new | Ne | Objednávka vytvořena |
processing | Ne | Platba probíhá |
completed | Ano | Platba úspěšná — doručte zboží |
cancelled | Ano | Platba zrušena zákazníkem |
expired | Ano | Platební odkaz vypršel |
error | Ano | Technická chyba |
Osvědčené postupy pro webhooky
- Vždy ověřte přes API — webhookový payload obsahuje pouze ID objednávky, nikdy stav. Metoda
verifyWebhook()SDK to dělá automaticky. - Vraťte HTTP 200 jako potvrzení přijetí. Jakýkoli jiný kód spustí až 10 opakování (po 2 minutách).
- Implementujte záložní polling — pro objednávky starší než 10 minut, které nedosáhly konečného stavu, dotazujte
getOrder()jako záchrannou síť. - Buďte idempotentní — stejný webhook můžete obdržet vícekrát.
Testovací karty
Tyto karty použijte v testovacím režimu Cost+ (sandbox web):
| Karta | Číslo | Poznámky |
|---|---|---|
| Visa (úspěch) | 4111 1111 1111 1111 | Libovolné CVV |
| Mastercard (úspěch) | 5544 3300 0003 7 | Libovolné CVV |
| Visa (zamítnuto) | 4111 1111 1111 1105 | Do Not Honor |
| Visa (nedostatek prostředků) | 4111 1111 1111 1151 | Insufficient Funds |
Použijte libovolné budoucí datum platnosti a libovolný 3místný CVC.
Demo aplikace
Demo aplikace založená na Dockeru (Ktor) je součástí GitHub repozitáře pro testování celého platebního toku.
Podpora
Potřebujete pomoc? Obraťte se na náš tým podpory na support@costplus.io.