curl --request POST \
--url http://localhost:8091/internal/v1/webhooks/ensure \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'X-Provider-Access-Token: <x-provider-access-token>' \
--data '
{
"connection_id": "<string>",
"provider_app_id": "<string>",
"external_store_id": "<string>",
"webhook_endpoint_id": "<string>",
"subscriptions": [
{
"url": "<string>",
"topics": [
"<string>"
]
}
]
}
'import requests
url = "http://localhost:8091/internal/v1/webhooks/ensure"
payload = {
"connection_id": "<string>",
"provider_app_id": "<string>",
"external_store_id": "<string>",
"webhook_endpoint_id": "<string>",
"subscriptions": [
{
"url": "<string>",
"topics": ["<string>"]
}
]
}
headers = {
"X-Provider-Access-Token": "<x-provider-access-token>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Provider-Access-Token': '<x-provider-access-token>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
connection_id: '<string>',
provider_app_id: '<string>',
external_store_id: '<string>',
webhook_endpoint_id: '<string>',
subscriptions: [{url: '<string>', topics: ['<string>']}]
})
};
fetch('http://localhost:8091/internal/v1/webhooks/ensure', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_PORT => "8091",
CURLOPT_URL => "http://localhost:8091/internal/v1/webhooks/ensure",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'connection_id' => '<string>',
'provider_app_id' => '<string>',
'external_store_id' => '<string>',
'webhook_endpoint_id' => '<string>',
'subscriptions' => [
[
'url' => '<string>',
'topics' => [
'<string>'
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"X-Provider-Access-Token: <x-provider-access-token>"
],
]);
$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 := "http://localhost:8091/internal/v1/webhooks/ensure"
payload := strings.NewReader("{\n \"connection_id\": \"<string>\",\n \"provider_app_id\": \"<string>\",\n \"external_store_id\": \"<string>\",\n \"webhook_endpoint_id\": \"<string>\",\n \"subscriptions\": [\n {\n \"url\": \"<string>\",\n \"topics\": [\n \"<string>\"\n ]\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Provider-Access-Token", "<x-provider-access-token>")
req.Header.Add("Authorization", "Bearer <token>")
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.post("http://localhost:8091/internal/v1/webhooks/ensure")
.header("X-Provider-Access-Token", "<x-provider-access-token>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"connection_id\": \"<string>\",\n \"provider_app_id\": \"<string>\",\n \"external_store_id\": \"<string>\",\n \"webhook_endpoint_id\": \"<string>\",\n \"subscriptions\": [\n {\n \"url\": \"<string>\",\n \"topics\": [\n \"<string>\"\n ]\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("http://localhost:8091/internal/v1/webhooks/ensure")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["X-Provider-Access-Token"] = '<x-provider-access-token>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"connection_id\": \"<string>\",\n \"provider_app_id\": \"<string>\",\n \"external_store_id\": \"<string>\",\n \"webhook_endpoint_id\": \"<string>\",\n \"subscriptions\": [\n {\n \"url\": \"<string>\",\n \"topics\": [\n \"<string>\"\n ]\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"subscriptions": 1
}Asegurar las suscripciones de webhook en el proveedor
La sirve el conector, no ingestion-api. Le pide que el proveedor entregue sus topics al endpoint propio del conector y, además, los listados a cada URL extra — los consumidores legacy durante el corte.
Es idempotente: se llama en cada instalación y en cada reinstalación, y llamarla de más no duplica suscripciones.
curl --request POST \
--url http://localhost:8091/internal/v1/webhooks/ensure \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'X-Provider-Access-Token: <x-provider-access-token>' \
--data '
{
"connection_id": "<string>",
"provider_app_id": "<string>",
"external_store_id": "<string>",
"webhook_endpoint_id": "<string>",
"subscriptions": [
{
"url": "<string>",
"topics": [
"<string>"
]
}
]
}
'import requests
url = "http://localhost:8091/internal/v1/webhooks/ensure"
payload = {
"connection_id": "<string>",
"provider_app_id": "<string>",
"external_store_id": "<string>",
"webhook_endpoint_id": "<string>",
"subscriptions": [
{
"url": "<string>",
"topics": ["<string>"]
}
]
}
headers = {
"X-Provider-Access-Token": "<x-provider-access-token>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Provider-Access-Token': '<x-provider-access-token>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
connection_id: '<string>',
provider_app_id: '<string>',
external_store_id: '<string>',
webhook_endpoint_id: '<string>',
subscriptions: [{url: '<string>', topics: ['<string>']}]
})
};
fetch('http://localhost:8091/internal/v1/webhooks/ensure', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_PORT => "8091",
CURLOPT_URL => "http://localhost:8091/internal/v1/webhooks/ensure",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'connection_id' => '<string>',
'provider_app_id' => '<string>',
'external_store_id' => '<string>',
'webhook_endpoint_id' => '<string>',
'subscriptions' => [
[
'url' => '<string>',
'topics' => [
'<string>'
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"X-Provider-Access-Token: <x-provider-access-token>"
],
]);
$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 := "http://localhost:8091/internal/v1/webhooks/ensure"
payload := strings.NewReader("{\n \"connection_id\": \"<string>\",\n \"provider_app_id\": \"<string>\",\n \"external_store_id\": \"<string>\",\n \"webhook_endpoint_id\": \"<string>\",\n \"subscriptions\": [\n {\n \"url\": \"<string>\",\n \"topics\": [\n \"<string>\"\n ]\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Provider-Access-Token", "<x-provider-access-token>")
req.Header.Add("Authorization", "Bearer <token>")
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.post("http://localhost:8091/internal/v1/webhooks/ensure")
.header("X-Provider-Access-Token", "<x-provider-access-token>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"connection_id\": \"<string>\",\n \"provider_app_id\": \"<string>\",\n \"external_store_id\": \"<string>\",\n \"webhook_endpoint_id\": \"<string>\",\n \"subscriptions\": [\n {\n \"url\": \"<string>\",\n \"topics\": [\n \"<string>\"\n ]\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("http://localhost:8091/internal/v1/webhooks/ensure")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["X-Provider-Access-Token"] = '<x-provider-access-token>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"connection_id\": \"<string>\",\n \"provider_app_id\": \"<string>\",\n \"external_store_id\": \"<string>\",\n \"webhook_endpoint_id\": \"<string>\",\n \"subscriptions\": [\n {\n \"url\": \"<string>\",\n \"topics\": [\n \"<string>\"\n ]\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"subscriptions": 1
}Autorizaciones
El conector de plataforma y el operador. Registra conexiones, entrega webhooks, corre la saga de instalación y da de alta conexiones custom. Es el único principal obligatorio del proceso: los otros tres se apagan dejando su token vacío, y una puerta que no se monta no la abre ningún token.
Encabezados
El token del merchant contra el proveedor. Viaja sólo en el header y nunca en el cuerpo, para que no termine en un log de request ni en un archivo de crudos.
1Cuerpo
Le pide al conector que el proveedor entregue sus topics al endpoint propio del conector y, además, los listados a cada URL extra (los consumidores legacy durante el corte). Es idempotente.
Respuesta
Cuántas suscripciones quedaron registradas.
x >= 0