curl --request PATCH \
--url https://tapipay-facade.homo.tapila.cloud/subscriptions/{id} \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--header 'x-authorization-token: <api-key>' \
--data '
{
"amount": 1.01,
"description": "<string>",
"additionalData": {
"source": "crm",
"folio": "F-2026-0042"
},
"enforcePaymentOrder": true,
"allowOverduePayment": true,
"autopay": true,
"paymentMethods": []
}
'import requests
url = "https://tapipay-facade.homo.tapila.cloud/subscriptions/{id}"
payload = {
"amount": 1.01,
"description": "<string>",
"additionalData": {
"source": "crm",
"folio": "F-2026-0042"
},
"enforcePaymentOrder": True,
"allowOverduePayment": True,
"autopay": True,
"paymentMethods": []
}
headers = {
"x-api-key": "<api-key>",
"x-authorization-token": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {
'x-api-key': '<api-key>',
'x-authorization-token': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: 1.01,
description: '<string>',
additionalData: {source: 'crm', folio: 'F-2026-0042'},
enforcePaymentOrder: true,
allowOverduePayment: true,
autopay: true,
paymentMethods: []
})
};
fetch('https://tapipay-facade.homo.tapila.cloud/subscriptions/{id}', 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://tapipay-facade.homo.tapila.cloud/subscriptions/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'amount' => 1.01,
'description' => '<string>',
'additionalData' => [
'source' => 'crm',
'folio' => 'F-2026-0042'
],
'enforcePaymentOrder' => true,
'allowOverduePayment' => true,
'autopay' => true,
'paymentMethods' => [
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>",
"x-authorization-token: <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"
"strings"
"net/http"
"io"
)
func main() {
url := "https://tapipay-facade.homo.tapila.cloud/subscriptions/{id}"
payload := strings.NewReader("{\n \"amount\": 1.01,\n \"description\": \"<string>\",\n \"additionalData\": {\n \"source\": \"crm\",\n \"folio\": \"F-2026-0042\"\n },\n \"enforcePaymentOrder\": true,\n \"allowOverduePayment\": true,\n \"autopay\": true,\n \"paymentMethods\": []\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("x-authorization-token", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("https://tapipay-facade.homo.tapila.cloud/subscriptions/{id}")
.header("x-api-key", "<api-key>")
.header("x-authorization-token", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"amount\": 1.01,\n \"description\": \"<string>\",\n \"additionalData\": {\n \"source\": \"crm\",\n \"folio\": \"F-2026-0042\"\n },\n \"enforcePaymentOrder\": true,\n \"allowOverduePayment\": true,\n \"autopay\": true,\n \"paymentMethods\": []\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://tapipay-facade.homo.tapila.cloud/subscriptions/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["x-api-key"] = '<api-key>'
request["x-authorization-token"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"amount\": 1.01,\n \"description\": \"<string>\",\n \"additionalData\": {\n \"source\": \"crm\",\n \"folio\": \"F-2026-0042\"\n },\n \"enforcePaymentOrder\": true,\n \"allowOverduePayment\": true,\n \"autopay\": true,\n \"paymentMethods\": []\n}"
response = http.request(request)
puts response.read_body{
"data": {
"subscriptionId": "sub_839d28e1-a175-40c7-a54b-55f6c17b7964",
"externalSubscriptionId": "SUB-2026-007",
"status": "ACTIVE",
"scheduling": {
"intervalUnit": "month",
"intervalCount": 1,
"startDate": "2026-06-15",
"totalCycles": 12,
"endDate": null,
"billingDay": {
"day": 15
}
},
"externalClientId": "CLI-00042",
"amount": 999,
"currency": "MXN",
"paymentUrl": "https://app.tapipay.la/s/acme-corp/portal/aB3dE5fG7h/debts",
"enforcePaymentOrder": false,
"autopay": false,
"allowOverduePayment": true,
"allowPartialPayments": true,
"paymentMethods": [
"CASH",
"CARD"
],
"description": "Plan Gimnasio",
"additionalData": {
"source": "crm"
},
"contact": {
"contactId": "con_9aL3kP2m",
"externalClientId": "CLI-00042",
"createdInline": false
},
"product": {
"productId": "prd_42",
"name": "Plan Gimnasio",
"active": true,
"createdInline": true
},
"createdAt": "2026-06-03T18:15:00.000Z",
"updatedAt": "2026-06-03T18:15:00.000Z"
},
"requestId": "<string>"
}Actualizar suscripción
Modifica el monto, la descripción y las opciones de cobro. Solo amount se aplica también a las deudas ya generadas (conservando pagos parciales y allowPartialPayments; las deudas canceladas no se modifican). Una suscripción CANCELLED o ENDED no se puede modificar. companyCode en el body se toma como contexto y no como campo a modificar.
curl --request PATCH \
--url https://tapipay-facade.homo.tapila.cloud/subscriptions/{id} \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--header 'x-authorization-token: <api-key>' \
--data '
{
"amount": 1.01,
"description": "<string>",
"additionalData": {
"source": "crm",
"folio": "F-2026-0042"
},
"enforcePaymentOrder": true,
"allowOverduePayment": true,
"autopay": true,
"paymentMethods": []
}
'import requests
url = "https://tapipay-facade.homo.tapila.cloud/subscriptions/{id}"
payload = {
"amount": 1.01,
"description": "<string>",
"additionalData": {
"source": "crm",
"folio": "F-2026-0042"
},
"enforcePaymentOrder": True,
"allowOverduePayment": True,
"autopay": True,
"paymentMethods": []
}
headers = {
"x-api-key": "<api-key>",
"x-authorization-token": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {
'x-api-key': '<api-key>',
'x-authorization-token': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: 1.01,
description: '<string>',
additionalData: {source: 'crm', folio: 'F-2026-0042'},
enforcePaymentOrder: true,
allowOverduePayment: true,
autopay: true,
paymentMethods: []
})
};
fetch('https://tapipay-facade.homo.tapila.cloud/subscriptions/{id}', 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://tapipay-facade.homo.tapila.cloud/subscriptions/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'amount' => 1.01,
'description' => '<string>',
'additionalData' => [
'source' => 'crm',
'folio' => 'F-2026-0042'
],
'enforcePaymentOrder' => true,
'allowOverduePayment' => true,
'autopay' => true,
'paymentMethods' => [
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>",
"x-authorization-token: <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"
"strings"
"net/http"
"io"
)
func main() {
url := "https://tapipay-facade.homo.tapila.cloud/subscriptions/{id}"
payload := strings.NewReader("{\n \"amount\": 1.01,\n \"description\": \"<string>\",\n \"additionalData\": {\n \"source\": \"crm\",\n \"folio\": \"F-2026-0042\"\n },\n \"enforcePaymentOrder\": true,\n \"allowOverduePayment\": true,\n \"autopay\": true,\n \"paymentMethods\": []\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("x-authorization-token", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("https://tapipay-facade.homo.tapila.cloud/subscriptions/{id}")
.header("x-api-key", "<api-key>")
.header("x-authorization-token", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"amount\": 1.01,\n \"description\": \"<string>\",\n \"additionalData\": {\n \"source\": \"crm\",\n \"folio\": \"F-2026-0042\"\n },\n \"enforcePaymentOrder\": true,\n \"allowOverduePayment\": true,\n \"autopay\": true,\n \"paymentMethods\": []\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://tapipay-facade.homo.tapila.cloud/subscriptions/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["x-api-key"] = '<api-key>'
request["x-authorization-token"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"amount\": 1.01,\n \"description\": \"<string>\",\n \"additionalData\": {\n \"source\": \"crm\",\n \"folio\": \"F-2026-0042\"\n },\n \"enforcePaymentOrder\": true,\n \"allowOverduePayment\": true,\n \"autopay\": true,\n \"paymentMethods\": []\n}"
response = http.request(request)
puts response.read_body{
"data": {
"subscriptionId": "sub_839d28e1-a175-40c7-a54b-55f6c17b7964",
"externalSubscriptionId": "SUB-2026-007",
"status": "ACTIVE",
"scheduling": {
"intervalUnit": "month",
"intervalCount": 1,
"startDate": "2026-06-15",
"totalCycles": 12,
"endDate": null,
"billingDay": {
"day": 15
}
},
"externalClientId": "CLI-00042",
"amount": 999,
"currency": "MXN",
"paymentUrl": "https://app.tapipay.la/s/acme-corp/portal/aB3dE5fG7h/debts",
"enforcePaymentOrder": false,
"autopay": false,
"allowOverduePayment": true,
"allowPartialPayments": true,
"paymentMethods": [
"CASH",
"CARD"
],
"description": "Plan Gimnasio",
"additionalData": {
"source": "crm"
},
"contact": {
"contactId": "con_9aL3kP2m",
"externalClientId": "CLI-00042",
"createdInline": false
},
"product": {
"productId": "prd_42",
"name": "Plan Gimnasio",
"active": true,
"createdInline": true
},
"createdAt": "2026-06-03T18:15:00.000Z",
"updatedAt": "2026-06-03T18:15:00.000Z"
},
"requestId": "<string>"
}Autorizaciones
API key del API Gateway de Tapi. Requerida en todas las operaciones. Distinta por ambiente (desarrollo, homologación, producción).
Token TAPI JWT. Requerido en todas las operaciones. Se envía sin prefijo "Bearer". Ej: x-authorization-token: eyJhbGci...
Parámetros de ruta
ID público con prefijo sub_ o el mismo valor sin prefijo.
"sub_839d28e1-a175-40c7-a54b-55f6c17b7964"
Cuerpo
Monto por ciclo en pesos (hasta 2 decimales, mínimo 0.01)
x >= 0.01Debe ser un múltiplo de 0.01Debe ser string (si no, 400).
Datos adicionales propios del cliente. Debe ser un objeto plano; un escalar (string, número o booleano) devuelve 400 INVALID_REQUEST. No puede usar claves reservadas, que TapiPay escribe internamente: description, paymentMethods, productName, externalProductId, debtExpirationDate, overduePayment, allowPartialPayments, recurringDebt, debtReference. Si aparece alguna, la API responde 400 INVALID_REQUEST con details[].field = additionalData. Se persiste en la deuda (en ligas de pago, en la deuda asociada al link; en suscripciones, en las deudas generadas).
{ "source": "crm", "folio": "F-2026-0042" }
Solo acepta true/false literal (si no, 400).
Solo acepta true/false literal (si no, 400).
Solo acepta true/false literal (si no, 400). autopay: true y paymentMethods son excluyentes (400).
Valores fuera del enum devuelven 400.
CASH, CARD, TRANSFER, WALLET, BANK_TRANSFER Respuesta
Suscripción actualizada
description, additionalData y paymentMethods solo vienen si tienen valor. Una suscripción ACTIVE cuya fecha de fin ya pasó se devuelve como ENDED.
Show child attributes
Show child attributes
{
"subscriptionId": "sub_839d28e1-a175-40c7-a54b-55f6c17b7964",
"externalSubscriptionId": "SUB-2026-007",
"status": "ACTIVE",
"scheduling": {
"intervalUnit": "month",
"intervalCount": 1,
"startDate": "2026-06-15",
"totalCycles": 12,
"endDate": null,
"billingDay": { "day": 15 }
},
"externalClientId": "CLI-00042",
"amount": 999,
"currency": "MXN",
"paymentUrl": "https://app.tapipay.la/s/acme-corp/portal/aB3dE5fG7h/debts",
"enforcePaymentOrder": false,
"autopay": false,
"allowOverduePayment": true,
"allowPartialPayments": true,
"paymentMethods": ["CASH", "CARD"],
"description": "Plan Gimnasio",
"additionalData": { "source": "crm" },
"contact": {
"contactId": "con_9aL3kP2m",
"externalClientId": "CLI-00042",
"createdInline": false
},
"product": {
"productId": "prd_42",
"name": "Plan Gimnasio",
"active": true,
"createdInline": true
},
"createdAt": "2026-06-03T18:15:00.000Z",
"updatedAt": "2026-06-03T18:15:00.000Z"
}

