Trigger immediate billing for an order
Queues a billing attempt for immediate processing, bypassing the scheduled billing date.
Asynchronous processing:
- A successful response means the billing attempt was accepted and processing has started; it does not contain the payment result
- The charge is sent to Shopify shortly after the call and the result is reported asynchronously
- Use
billingAttemptIdfrom the response to track the result; it can differ from the requested ID depending on shop settings
Tracking the result:
- Webhooks:
subscription.billing-successorsubscription.billing-failure - Polling:
GET /api/external/v2/subscription-billing-attempts/past-orders?contractId={contractId}and check the attemptstatus:IMMEDIATE_TRIGGERED/PROGRESS: still processingSECURITY_CHALLENGE: the card issuer requires 3D Secure; no webhook is sent for this stateSUCCESS/FAILURE: final result
Important Notes:
- Requires shop permission ‘enableImmediatePlaceOrder’
- Creates an actual order in Shopify and charges the customer’s payment method
- Cannot be undone once processed
Authentication: Requires valid X-API-Key header and shop permission
curl --request PUT \
--url https://subscription-admin.appstle.com/api/external/v2/subscription-billing-attempts/attempt-billing/{id}import requests
url = "https://subscription-admin.appstle.com/api/external/v2/subscription-billing-attempts/attempt-billing/{id}"
response = requests.put(url)
print(response.text)const options = {method: 'PUT'};
fetch('https://subscription-admin.appstle.com/api/external/v2/subscription-billing-attempts/attempt-billing/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));const url = 'https://subscription-admin.appstle.com/api/external/v2/subscription-billing-attempts/attempt-billing/{id}';
const options = {method: 'PUT'};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://subscription-admin.appstle.com/api/external/v2/subscription-billing-attempts/attempt-billing/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
]);
$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://subscription-admin.appstle.com/api/external/v2/subscription-billing-attempts/attempt-billing/{id}"
req, _ := http.NewRequest("PUT", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}require 'uri'
require 'net/http'
url = URI("https://subscription-admin.appstle.com/api/external/v2/subscription-billing-attempts/attempt-billing/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
response = http.request(request)
puts response.read_body{
"billingAttemptId": 123456,
"billingDate": "2026-09-26T10:15:30Z",
"contractId": 987654321,
"message": "Billing attempt has been queued for immediate processing. The payment result is not included in this response. Track it via the subscription.billing-success / subscription.billing-failure webhooks, or poll GET /api/external/v2/subscription-billing-attempts/past-orders?contractId={contractId} using the returned billingAttemptId.",
"requestedBillingAttemptId": 123456,
"status": "IMMEDIATE_TRIGGERED"
}{
"billingAttemptId": 123457,
"billingDate": "2023-11-07T05:31:56Z",
"contractId": 987654321,
"message": "<string>",
"requestedBillingAttemptId": 123456,
"status": "IMMEDIATE_TRIGGERED"
}{
"billingAttemptId": 123457,
"billingDate": "2023-11-07T05:31:56Z",
"contractId": 987654321,
"message": "<string>",
"requestedBillingAttemptId": 123456,
"status": "IMMEDIATE_TRIGGERED"
}{
"detail": "Shop does not have enableImmediatePlaceOrder permission",
"status": 403,
"title": "Permission denied",
"type": "https://example.com/errors/forbidden"
}Headers
Path Parameters
Billing Attempt ID
Query Parameters
API Key (Deprecated - Use Header X-API-Key instead)
Response
Billing attempt accepted and queued for immediate processing
Acknowledgement that an immediate billing attempt was accepted and queued for processing. The payment result is delivered asynchronously.
Billing attempt ID that is being processed. Can differ from requestedBillingAttemptId depending on shop settings; use this ID to track the result.
123457
Billing date of the attempt being processed
Subscription contract ID
987654321
Human readable description of what happens next
Billing attempt ID that was passed in the request
123456
Current status of the billing attempt
SUCCESS, FAILURE, REQUESTING, PROGRESS, QUEUED, SKIPPED, SOCIAL_CONNECTION_NULL, CONTRACT_CANCELLED, CONTRACT_ENDED, CONTRACT_PAUSED, AUTO_CHARGE_DISABLED, SHOPIFY_EXCEPTION, SKIPPED_DUNNING_MGMT, SKIPPED_INVENTORY_MGMT, IMMEDIATE_TRIGGERED, SECURITY_CHALLENGE, CONTRACT_PAUSED_MAX_CYCLES, REFUNDED, SKIPPED_DEMO_SHOP, SKIPPED_SHOP_INFO_NOT_FOUND, SKIPPED_BILLING_DATE_STALE, SKIPPED_DUNNING_NOT_CONFIGURED, PENDING_CONSOLIDATION "IMMEDIATE_TRIGGERED"
curl --request PUT \
--url https://subscription-admin.appstle.com/api/external/v2/subscription-billing-attempts/attempt-billing/{id}import requests
url = "https://subscription-admin.appstle.com/api/external/v2/subscription-billing-attempts/attempt-billing/{id}"
response = requests.put(url)
print(response.text)const options = {method: 'PUT'};
fetch('https://subscription-admin.appstle.com/api/external/v2/subscription-billing-attempts/attempt-billing/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));const url = 'https://subscription-admin.appstle.com/api/external/v2/subscription-billing-attempts/attempt-billing/{id}';
const options = {method: 'PUT'};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://subscription-admin.appstle.com/api/external/v2/subscription-billing-attempts/attempt-billing/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
]);
$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://subscription-admin.appstle.com/api/external/v2/subscription-billing-attempts/attempt-billing/{id}"
req, _ := http.NewRequest("PUT", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}require 'uri'
require 'net/http'
url = URI("https://subscription-admin.appstle.com/api/external/v2/subscription-billing-attempts/attempt-billing/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
response = http.request(request)
puts response.read_body{
"billingAttemptId": 123456,
"billingDate": "2026-09-26T10:15:30Z",
"contractId": 987654321,
"message": "Billing attempt has been queued for immediate processing. The payment result is not included in this response. Track it via the subscription.billing-success / subscription.billing-failure webhooks, or poll GET /api/external/v2/subscription-billing-attempts/past-orders?contractId={contractId} using the returned billingAttemptId.",
"requestedBillingAttemptId": 123456,
"status": "IMMEDIATE_TRIGGERED"
}{
"billingAttemptId": 123457,
"billingDate": "2023-11-07T05:31:56Z",
"contractId": 987654321,
"message": "<string>",
"requestedBillingAttemptId": 123456,
"status": "IMMEDIATE_TRIGGERED"
}{
"billingAttemptId": 123457,
"billingDate": "2023-11-07T05:31:56Z",
"contractId": 987654321,
"message": "<string>",
"requestedBillingAttemptId": 123456,
"status": "IMMEDIATE_TRIGGERED"
}{
"detail": "Shop does not have enableImmediatePlaceOrder permission",
"status": 403,
"title": "Permission denied",
"type": "https://example.com/errors/forbidden"
}