Set Up Payment Link Wallet
curl --request POST \
--url https://api.hopnow.io/v1/accounts/{account_id}/payment-link-wallets \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.hopnow.io/v1/accounts/{account_id}/payment-link-wallets"
headers = {"X-API-Key": "<api-key>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.hopnow.io/v1/accounts/{account_id}/payment-link-wallets', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.hopnow.io/v1/accounts/{account_id}/payment-link-wallets",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.hopnow.io/v1/accounts/{account_id}/payment-link-wallets"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.hopnow.io/v1/accounts/{account_id}/payment-link-wallets")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.hopnow.io/v1/accounts/{account_id}/payment-link-wallets")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_bodyPayment Links
Set Up Payment Link Wallet
Prepare an account and currency for hosted payment links
POST
/
v1
/
accounts
/
{account_id}
/
payment-link-wallets
Set Up Payment Link Wallet
curl --request POST \
--url https://api.hopnow.io/v1/accounts/{account_id}/payment-link-wallets \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.hopnow.io/v1/accounts/{account_id}/payment-link-wallets"
headers = {"X-API-Key": "<api-key>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.hopnow.io/v1/accounts/{account_id}/payment-link-wallets', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.hopnow.io/v1/accounts/{account_id}/payment-link-wallets",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.hopnow.io/v1/accounts/{account_id}/payment-link-wallets"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.hopnow.io/v1/accounts/{account_id}/payment-link-wallets")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.hopnow.io/v1/accounts/{account_id}/payment-link-wallets")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_bodyCreate this resource once per account and currency before creating payment links. It is separate from deposit wallets and has no deposit address. One payment link wallet supports all of its
available_networks; the selected network and deposit address belong to each payment request.
Requires payins:write, an active account, approved payment-link onboarding, and an available network for the currency.
Request
{"currency": "USDT"}
currency is required and accepts USDT or USDC. Do not pass network or a provider wallet ID.
Response
Successful calls always return HTTP201, including when this account already has a payment link wallet for the currency. Repeat calls return the same ID and current stored status. An Idempotency-Key is not required: the account and currency identify the resource, including for concurrent calls.
{
"object": "payment_link_wallet",
"id": "plw_9z3mx7k2v8q1n6r4t0p5cahb",
"account_id": "acct_y7mxdf48446z91cqfdx6vym3",
"currency": "USDT",
"status": "pending",
"available_networks": ["ethereum"],
"created": "2026-10-21T06:00:00Z",
"updated": "2026-10-21T06:00:00Z",
"created_by": "ak_9admlg0248ynbfm2ci1qicry",
"updated_by": "ak_9admlg0248ynbfm2ci1qicry"
}
available_networks reflects enabled networks with configured treasury routing and can change. Use a network from the latest response.
| Status | Next step |
|---|---|
pending | Wait for payment_link_wallet.updated or poll the GET endpoint. |
ready | Create payment links for the same account and currency. |
failed | Contact support with the wallet ID; repeating POST does not create a replacement. |
Integration sequence
- Subscribe to payment_link_wallet.updated before setup.
- Call this endpoint and store the returned
plw_ID. If the response is alreadyready, continue immediately;201alone does not mean ready. - Wait for the
payment_link_wallet.updatedwebhook or use Get Payment Link Wallet. Handle duplicate webhooks using the event ID and checkdata.status. - Create a payment link using this account and currency. Repeat step 4 for subsequent links.
payment_link_wallet.updated when the wallet becomes ready or failed. Use GET if that notification is delayed or missed.
If the setup response is lost or a provider error occurs, repeat POST with the same account and currency. It returns the existing resource, and retries provisioning if the first attempt did not reach the provider. If the status stays pending after a successful retry, wait for the readiness webhook or poll GET.
Accounts with earlier payment links must also perform setup once. Hop adopts an existing matching provider wallet where one exists, keeping the same settlement destination.