Azupay
Elixir client library for the AzuPay Payments API.
Installation
Add azupay to your list of dependencies in mix.exs:
def deps do
[
{:azupay, "~> 0.1.0"}
]
endConfiguration
Configure environments in your config/runtime.exs:
config :azupay,
environments: [
uat: [
base_url: "https://api-uat.azupay.com.au/v1",
api_key: System.get_env("AZUPAY_UAT_API_KEY"),
client_id: System.get_env("AZUPAY_UAT_CLIENT_ID")
],
prod: [
base_url: "https://api.azupay.com.au/v1",
api_key: System.get_env("AZUPAY_PROD_API_KEY"),
client_id: System.get_env("AZUPAY_PROD_CLIENT_ID")
]
]Usage
Creating a Client
# Create a client for an environment
client = Azupay.Client.new(environment: :uat)
# Shortcut for UAT
client = Azupay.Client.uat()Payment Requests
Generate PayID or virtual account details for receiving payments.
# Create a payment request
{:ok, response} = Azupay.Client.PaymentRequests.create(client, %{
"payID" => "user@example.com",
"payIDType" => "EMAIL",
"amount" => "100.00",
"clientTransactionId" => "txn-123"
})
# Get a payment request
{:ok, response} = Azupay.Client.PaymentRequests.get(client, "request-id")
# Search payment requests
{:ok, results} = Azupay.Client.PaymentRequests.search(client, %{
"fromDate" => "2025-01-01T00:00:00Z",
"toDate" => "2025-01-31T23:59:59Z"
})
# Refund a payment request (full or partial)
{:ok, response} = Azupay.Client.PaymentRequests.refund(client, "request-id")
{:ok, response} = Azupay.Client.PaymentRequests.refund(client, "request-id", refund_amount: "50.00")
# Delete a payment request
{:ok, response} = Azupay.Client.PaymentRequests.delete(client, "request-id")Payments
Disburse funds via PayID or BSB/account number.
# Create a payment
{:ok, response} = Azupay.Client.Payments.create(client, %{
"clientPaymentId" => "pay-123",
"amount" => "250.00",
"payID" => "recipient@example.com",
"payIDType" => "EMAIL"
})
# Get a payment
{:ok, response} = Azupay.Client.Payments.get(client, "payment-id")
# Search payments
{:ok, results} = Azupay.Client.Payments.search(client, %{
"clientPaymentId" => "pay-123"
})Payment Initiations (PayTo)
Collect funds from payers with active payment agreements.
# Create a payment initiation
{:ok, response} = Azupay.Client.PaymentInitiations.create(client, %{
"clientTransactionId" => "pi-123",
"amount" => "100.00",
"paymentAgreementId" => "agreement-id"
})
# Get a payment initiation
{:ok, response} = Azupay.Client.PaymentInitiations.get(client, "initiation-id")
# Refund a payment initiation
{:ok, response} = Azupay.Client.PaymentInitiations.refund(client, "initiation-id")Payment Agreements (PayTo Mandates)
# Create a payment agreement
{:ok, response} = Azupay.Client.PaymentAgreements.create(client, %{
"contractId" => "contract-123",
"payerPayID" => "payer@example.com",
"payerPayIDType" => "EMAIL"
})
# Search agreements
{:ok, results} = Azupay.Client.PaymentAgreements.search(client, %{
"contractId" => "contract-123"
})
# Amend an agreement
{:ok, response} = Azupay.Client.PaymentAgreements.amend(client, %{
"paymentAgreementId" => "agreement-id",
"amount" => "200.00"
})
# Change agreement status (ACTIVE, SUSPENDED, CANCELLED)
{:ok, response} = Azupay.Client.PaymentAgreements.change_status(client, "agreement-id", "SUSPENDED")Payment Agreement Requests
Initiate payer approval flow for PayTo agreements.
{:ok, response} = Azupay.Client.PaymentAgreementRequests.create(client, %{
"contractId" => "contract-123",
"payerPayID" => "payer@example.com",
"payerPayIDType" => "EMAIL"
})
# Response includes `sessionUrl` for redirecting the payerAccount Enquiry
# Check BSB reachability
{:ok, response} = Azupay.Client.Accounts.check_bsb(client, %{"bsb" => "062000"})
# Check PayID status
{:ok, response} = Azupay.Client.Accounts.check_payid(client, %{
"payID" => "user@example.com",
"payIDType" => "EMAIL"
})
# Confirmation of Payee (CoP)
{:ok, response} = Azupay.Client.Accounts.check_account(client, %{
"accountCheckId" => "check-123",
"bsb" => "062000",
"accountNumber" => "12345678",
"accountName" => "John Doe",
"purposeCode" => "SALARY",
"additionalDetails" => "Payroll"
})Balances
{:ok, balance} = Azupay.Client.Balances.get(client)Balance Adjustments
{:ok, response} = Azupay.Client.BalanceAdjustments.create(client, %{
"clientTransactionId" => "adj-123",
"adjustmentAmount" => "500.00",
"adjustmentType" => "CREDIT",
"reason" => "Top up",
"clientId" => "client-id"
})Reports
# List reports
{:ok, reports} = Azupay.Client.Reports.list(client, %{
"clientId" => "client-id",
"month" => "2025-01",
"timezone" => "Australia/Sydney"
})
# Get download URL
{:ok, url} = Azupay.Client.Reports.download_url(client, "client-id", "report-id")API Keys
# Create an API key for a sub-merchant
{:ok, key} = Azupay.Client.ApiKeys.create(client, %{"clientId" => "sub-merchant-id"})
# List all API keys
{:ok, keys} = Azupay.Client.ApiKeys.list(client)
# Get a specific API key
{:ok, key} = Azupay.Client.ApiKeys.get(client, "key-id")
# Update an API key
{:ok, key} = Azupay.Client.ApiKeys.update(client, "key-id", %{"enabled" => false})Sub-Client Management
# Create a sub-client
{:ok, response} = Azupay.Client.Clients.create(client, %{
"clientTransactionId" => "client-123",
"name" => "Sub Merchant"
})
# Disable a sub-client
{:ok, response} = Azupay.Client.Clients.disable(client, "sub-client-id")
# Set low balance alert threshold
{:ok, response} = Azupay.Client.Clients.set_low_balance_threshold(client, "client-id", "1000.00")
# Set alert email addresses
{:ok, response} = Azupay.Client.Clients.set_alert_emails(client, "client-id", ["alerts@example.com"])PayID Domains
# List configured PayID domains
{:ok, domains} = Azupay.Client.PayIdDomains.list(client)
# Upsert PayID domains
{:ok, response} = Azupay.Client.PayIdDomains.upsert(client, [
%{"domain" => "example.com", "clientId" => "client-id"}
])
# Delete a PayID domain
{:ok, response} = Azupay.Client.PayIdDomains.delete(client, "example.com")API Resources
| Module | Description |
|---|---|
Azupay.Client.PaymentRequests | PayID/virtual account payment collection |
Azupay.Client.Payments | Fund disbursement via PayID or BSB |
Azupay.Client.PaymentInitiations | PayTo fund collection |
Azupay.Client.PaymentAgreements | PayTo recurring mandates |
Azupay.Client.PaymentAgreementRequests | PayTo payer approval flow |
Azupay.Client.Accounts | BSB, PayID, and account enquiry |
Azupay.Client.Balances | Account balance |
Azupay.Client.BalanceAdjustments | Ledger adjustments |
Azupay.Client.Reports | Report listing and download |
Azupay.Client.ApiKeys | API key management |
Azupay.Client.Clients | Sub-client management |
Azupay.Client.PayIdDomains | PayID domain configuration |
Error Handling
All functions return {:ok, data} or {:error, reason}. Error reasons include:
| Error | HTTP Status |
|---|---|
:unauthorized | 401 |
:forbidden | 403 |
:not_found | 404 |
{:validation_error, details} | 422 |
{:client_error, status, body} | Other 4xx |
{:server_error, status, body} | 5xx |
{:request_failed, reason} | Network failure |
Use Azupay.Client.Error.new/1 for structured error handling:
case Azupay.Client.PaymentRequests.create(client, params) do
{:ok, response} -> handle_success(response)
{:error, reason} ->
error = Azupay.Client.Error.new(reason)
if Azupay.Client.Error.validation_error?(error) do
handle_validation_error(error)
else
handle_error(error)
end
endTesting
Tests use Req's built-in plug adapter for HTTP mocking (no real HTTP calls):
client = Azupay.Client.new(
environment: :uat,
req_options: [
plug: fn conn ->
conn
|> Plug.Conn.put_resp_content_type("application/json")
|> Plug.Conn.send_resp(200, Jason.encode!(%{"status" => "ok"}))
end
]
)License
MIT