iOS SDK (Swift)

Full contract reference: see clients/CONTRACT.md in the backend repo.

Installation

// Package.swift
.package(path: "../clients/ios")
// Then depend on the "OneMyPosMate" product

Quick Start

let client = OneMyPosMateClient(
    baseUrl: "https://payus.co.nz",
    system: "pos"
)

let resp = try await client.payments.payNow(
    PayNowRequest(
        grandTotal: "10.00",
        referenceId: "REF-001",
        branchId: 17,
        configId: 123,
        channel: "WECHAT"
    )
)

Authentication Flow

// 1. Activate (one-time)
try await client.auth.activate(activationCode: "ABC123")

// 2. Token cached in Keychain (KeychainTokenStore)
// Every call auto-refreshes if within 60s of expiry
let token = try await client.auth.currentToken()

// 3. Actor-isolated single-flight Task prevents concurrent refreshes

Error Handling

do {
    try await client.payments.payNow(request)
} catch let error as OneMyPosMateError {
    switch error.errorCode {
    case .ERR_GATEWAY_NOT_FOUND: // Terminal not configured
    case .ERR_DUPLICATE_TRANSACTION: // referenceId reused
    case .ERR_UNAUTHORIZED: // Token expired, SDK auto-retried
    default: break
    }
}

Common Error Codes

CodeHTTPMeaning
ERR_GATEWAY_NOT_FOUND422Terminal gateway not configured
ERR_DUPLICATE_TRANSACTION409referenceId already used
ERR_REFUND_EXCEEDED400Refund amount > remaining balance
ERR_UNAUTHORIZED401Token expired (SDK auto-retries once)
ERR_FORBIDDEN403Tenant isolation violation
ERR_RATE_LIMITED429Too many requests
ERR_SYSTEM_ERROR500Server error (SDK retries 3x)