Stripe sources and integration configuration
Use member operations for legacy customer/card/method setup. The separate integration operations configure a resource’s Stripe connection and require authorized admin context. Choose the matching path in the payment-source guide. The token route consumes a provider token; it does not generate one.
Legacy customer-creation context
This section applies to the two customer-creation calls below. Use the member and resource context.
For these customer-creation paths, the resource default_paysystem selects the operator (fallback stripe), despite the Stripe route name. This walkthrough assumes stripe with existing configured account/key and resource payments_in_live_mode (default true).
Provider creation consumes an existing provider token and member email/name; local customer/card import follows, with conditional auto_attach_customer_to_resource (default true), unchecked saves and local card-default changes. Attachment exceptions are swallowed.
These steps have no shared transaction or idempotency guarantee. They do not prove a charge or entitlement; inspect state before retrying. Tokens are not Wallkit member tokens, provider customer IDs, method IDs or SetupIntent IDs.
Member source operations
| Task | Operation |
|---|---|
| Create a legacy customer from token input | Create a legacy customer from token input |
| Create a legacy customer with a provider token | Create a legacy customer with a provider token |
| Attach and persist a legacy payment method | Attach and persist a legacy payment method |
| Delete a local customer record | Delete a local customer record |
Authorized administrator context
These integration actions require admin access; partner inherits that grant and root bypasses ACL. Ordinary user access is insufficient; service_account has no grant for these actions.
Stripe controller initialization also requires an active user and valid resource, with session/resource locks applying. Use an existing authorized admin context in custom token header plus resource public key, as described in integration credentials. Examples use ADMIN_TOKEN as an existing supplied credential; they do not mint one.
Keep these calls and returned private credentials in trusted server/admin handling.
The selected header resource is the settings target. The actions add no independent connected-account owner/partner match or callback-state validation. Existing administrator authority must select the intended account/resource.
StripeOperator initialization also requires a configured base private key for resource payments_in_live_mode (default true), even though these actions inspect or select another mode.
Authorized integration-admin operations
| Task | Operation |
|---|---|
| Read Stripe integration authorization guidance | Read Stripe integration authorization guidance |
| Exchange a Stripe integration authorization code | Exchange a Stripe integration authorization code |
| Clear Stripe connection settings and conditionally deauthorize | Clear Stripe connection settings and conditionally deauthorize |
Example runtimes, base-address conventions and synthetic values follow response conventions.
Create a legacy customer from token input
This customer_id field is passed into provider customer creation as a token. Supplying an existing cus_ customer identifier is not an existing-customer import through this action.
POST /api/v1/user/stripe/customer
Before you call
Use the member and resource context; apply this operation’s provider and record requirements below.
Use the legacy customer-creation context. Keep this operation’s body field and error codes as specified below.
Request
JSON object required; form fields not used.
| Name | Location | Type / requirement | Meaning |
|---|---|---|---|
| customer_id | JSON | required nonempty; string/trim | Existing provider token used to create customer, despite name. Use the provider-client token appropriate for configured operator. |
Result
HTTP 201 top-level legacy customer record, with cards rather than payment_methods; created customer can exist without resource attachment/default. No user/profile wrapper.
Example: Create a customer using tok_SYNTHETIC
Despite its name, customer_id carries a provider token here. The result supplies a new provider customer identifier and local card records.
curl -X POST "${WALLKIT_API_BASE}/api/v1/user/stripe/customer" \
-H "token: ${USER_TOKEN}" \
-H "resource: ${RESOURCE_KEY}" \
-H "Content-Type: application/json" \
--data '{"customer_id":"tok_SYNTHETIC"}'
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/user/stripe/customer`, {
method: "POST",
headers: {token: process.env.USER_TOKEN, resource: process.env.RESOURCE_KEY, "Content-Type": "application/json"},
body: JSON.stringify({"customer_id":"tok_SYNTHETIC"})
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
body = {'customer_id': 'tok_SYNTHETIC'}
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/user/stripe/customer",
method="POST", headers={"token": os.environ["USER_TOKEN"],
"resource": os.environ["RESOURCE_KEY"], "Content-Type": "application/json"}, data=json.dumps(body).encode("utf-8"))
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 201 response excerpt:
{
"id": 4001,
"pay_system": "stripe",
"customer_id": "cus_SYNTHETIC",
"cards": [
{
"id": 5001,
"card_last4": "0000"
}
]
}
Consequential alternate
An existing provider customer ID can fail creation with HTTP 500 incorrect_customer. If importing that customer is intended, choose legacy generic customer import instead.
Recovery
| Status | Code | Cause | Next action |
|---|---|---|---|
| 406 | incorrect_data / incorrect_customer_id | No JSON/nonempty input. | Send JSON with the intended provider token. |
| 500 | incorrect_customer | Provider customer creation/import error. | Inspect correct token/account and partial customer/card state. |
| 500 | internal_error | Other configuration/local error. | Have administrator inspect selected provider and saved records before repeating. |
Next task
List cards in this resource to choose local user_card_id, such as 5001, for checkout.
Create a legacy customer with a provider token
Consume an existing provider token to create a customer and import cards. No token is generated by this route.
POST /api/v1/user/stripe/token
Before you call
Use the member and resource context; apply this operation’s provider and record requirements below.
Use the legacy customer-creation context. Keep this operation’s body field and error codes as specified below.
Request
JSON object required.
| Name | Location | Type / requirement | Meaning |
|---|---|---|---|
| token | JSON | required nonempty trimmed string | Existing provider-client token, tok_SYNTHETIC here; not token header/member credential. |
Result
HTTP 201 top-level legacy customer record, with cards rather than payment_methods; created customer can exist without resource attachment/default. No user/profile wrapper.
Example: Consume tok_SYNTHETIC to create a customer
Supply the provider token under token. The customer result can contain no imported cards; this call does not generate another token.
curl -X POST "${WALLKIT_API_BASE}/api/v1/user/stripe/token" \
-H "token: ${USER_TOKEN}" \
-H "resource: ${RESOURCE_KEY}" \
-H "Content-Type: application/json" \
--data '{"token":"tok_SYNTHETIC"}'
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/user/stripe/token`, {
method: "POST",
headers: {token: process.env.USER_TOKEN, resource: process.env.RESOURCE_KEY, "Content-Type": "application/json"},
body: JSON.stringify({"token":"tok_SYNTHETIC"})
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
body = {'token': 'tok_SYNTHETIC'}
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/user/stripe/token",
method="POST", headers={"token": os.environ["USER_TOKEN"],
"resource": os.environ["RESOURCE_KEY"], "Content-Type": "application/json"}, data=json.dumps(body).encode("utf-8"))
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 201 response excerpt:
{
"id": 4001,
"pay_system": "stripe",
"customer_id": "cus_SYNTHETIC",
"cards": []
}
Consequential alternate
HTTP 201 cards:[] is a customer projection without imported local card rows. It is not a checkout source ID. Provider/local errors may follow creation effects.
Recovery
| Status | Code | Cause | Next action |
|---|---|---|---|
| 406 | incorrect_data / incorrect_token | No JSON or empty token. | Supply provider token in JSON; member token remains header. |
| 406 | incorrect_create_payment_customer | Provider customer creation/retrieval error. | Check selected account/token and inspect partial state before retry. |
| 406 | incorrect_retrieve_card | Card import failure. | Inspect created customer and local cards. |
| 406 | incorrect_retrieve_token | Other failure/configuration. | Check configured provider and saved state; do not assume no writes. |
Next task
Read owned customers and cards before checkout.
Attach and persist a legacy payment method
Retrieve a provider method, attach it to the supplied provider customer, then save a local method associated with supplied local customer/card IDs. This does not confirm a PaymentIntent/SetupIntent, charge or establish a local/provider default.
POST /api/v1/user/stripe/confirm-payment-method
Before you call
Use the member and resource context; apply this operation’s provider and record requirements below.
Requires configured Stripe keys/account; initStripe uses resource payment mode and switches connected-account key when configured.
No explicit local customer/card ownership, resource membership, provider-customer match, duplicate check, or intent ID/status proof. Trusted integration must supply matching member-owned provider and local records.
Provider attachment occurs before local save; false save returns an error without undoing attachment.
No encompassing transaction/replay guarantee.
The action reads first supplied card ID but does not create or validate that card.
Request
JSON object required; nested fields are read directly without individual presence validation.
| Name | Location | Type / requirement | Meaning |
|---|---|---|---|
| intent.payment_method | JSON | required provider ID string | Existing Stripe method retrieved/attached; no other intent field used. |
| customer.customer_id | JSON | required provider customer string | Stripe attachment destination. |
| customer.id | JSON | required local numeric ID | Saved into payment_customer_id without ownership/match lookup. |
| customer.cards[0].id | JSON | required first local card numeric ID | Saved card_id; no card creation/validation. |
Result
HTTP 201 raw refreshed model toArray uses raw confirmed method. It has no nested user_card addition and does not use compact source DTO or modern asArray projection.
Example: Attach pm_SYNTHETIC and save method 3001
Supply matching provider customer and trusted local customer/card references. The result’s local method 3001 is distinct from the provider method ID and does not prove intent confirmation.
curl -X POST "${WALLKIT_API_BASE}/api/v1/user/stripe/confirm-payment-method" \
-H "token: ${USER_TOKEN}" \
-H "resource: ${RESOURCE_KEY}" \
-H "Content-Type: application/json" \
--data '{"intent":{"payment_method":"pm_SYNTHETIC"},"customer":{"id":4001,"customer_id":"cus_SYNTHETIC","cards":[{"id":5001}]}}'
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/user/stripe/confirm-payment-method`, {
method: "POST",
headers: {token: process.env.USER_TOKEN, resource: process.env.RESOURCE_KEY, "Content-Type": "application/json"},
body: JSON.stringify({"intent":{"payment_method":"pm_SYNTHETIC"},"customer":{"id":4001,"customer_id":"cus_SYNTHETIC","cards":[{"id":5001}]}})
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
body = {'intent': {'payment_method': 'pm_SYNTHETIC'}, 'customer': {'id': 4001, 'customer_id': 'cus_SYNTHETIC', 'cards': [{'id': 5001}]}}
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/user/stripe/confirm-payment-method",
method="POST", headers={"token": os.environ["USER_TOKEN"],
"resource": os.environ["RESOURCE_KEY"], "Content-Type": "application/json"}, data=json.dumps(body).encode("utf-8"))
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 201 response excerpt:
{
"id": 3001,
"payment_method_id": "pm_SYNTHETIC",
"customer_id": "cus_SYNTHETIC",
"payment_customer_id": 4001,
"card_id": 5001
}
Consequential alternate
HTTP 406 payment_method_saving_errors reports concatenated local validation messages after provider attachment. Inspect the provider association and local source list before deciding whether a corrected persistence step is needed.
Recovery
| Status | Code | Cause | Next action |
|---|---|---|---|
| 406 | incorrect_data | No JSON body. | Send the nested object. |
| 406 | payment_method_saving_errors | Local save returns false after attach. | Correct trusted local associations and inspect provider attachment first. |
| 406 | confirm_stripe_payment_method_error | Provider/configuration/other caught failure. | Inspect supplied IDs and configured account; do not equate this with no provider change. |
Next task
Read modern sources with matching provider context; use local method id 3001 for member calculation.
Delete a local customer record
Attempt deletion of the local customer. This action does not call Stripe customer deletion or explicitly remove cards/methods/resource relationships. Database relationship behavior is not established by these model definitions.
DELETE /api/v1/user/stripe/customer/{id}
Before you call
Use the member and resource context; apply this operation’s provider and record requirements below.
Lookup requires local customer owner/current resource attachment/ID. Despite the route name, the lookup does not check pay_system or mode. A local customer of another provider can match. The record can be shared with other resources; deleting it is not limited to an attachment removal. No cancellation/refund/provider erasure guarantee.
Request
Bodyless. id path required digits: local customer record ID from owned customer list, not provider customer_id.
Result
HTTP 200 result boolean from delete return value. false is a business failure even with HTTP 200; no deleted record returned.
Example: Remove local customer 4001
Delete an owned customer attached to the selected resource. result reports local deletion only, with no provider customer cleanup.
curl -X DELETE "${WALLKIT_API_BASE}/api/v1/user/stripe/customer/4001" \
-H "token: ${USER_TOKEN}" \
-H "resource: ${RESOURCE_KEY}"
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/user/stripe/customer/4001`, {
method: "DELETE",
headers: {token: process.env.USER_TOKEN, resource: process.env.RESOURCE_KEY}
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/user/stripe/customer/4001",
method="DELETE", headers={"token": os.environ["USER_TOKEN"],
"resource": os.environ["RESOURCE_KEY"]})
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 200 response excerpt:
{
"result": true
}
Consequential alternate
HTTP 200 {"result":false} means delete reported failure. HTTP 409 incorrect_user_payment_customer_id means no owned resource-attached local record matched.
Recovery
| Status | Code | Cause | Next action |
|---|---|---|---|
| 409 | incorrect_user_payment_customer_id | Local customer absent/wrong owner/resource. | Read owned customers and selected-resource visibility. |
| 200 | result:false | Local delete returned false. | Inspect remaining local records; do not assume cleanup or provider deletion. |
Next task
List owned customers and selected-resource sources to inspect what remains. Provider cleanup is not performed by this action.
Raw confirmed method
Raw model properties are selected, without user_card expansion. Unlike modern asArray, this uses all declared model fields. No explicit scalar conversion is shown.
| Field | Type / presence | Meaning |
|---|---|---|
| id | stored integer | Local saved method ID. |
| payment_method_id, customer_id | provider string | Retrieved method and attached provider customer identifiers. |
| created | stored integer | Provider creation value, unit not converted locally. |
| created_at, updated_at | string | Local Y-m-d H:i:s, timezone unspecified. |
| livemode | stored flag | Provider mode flag; no additional mode validation. |
| default | stored flag / unset or null | Action never sets it; database default/output representation unspecified. Do not infer true. |
| metadata, billing_details, card | JSON-encoded text or string | Provider objects encoded; non-object values string-cast here. Dynamic provider fields remain open. |
| object, type | provider string / nullable annotation | Provider labels; no complete enum established. |
| user_id | stored integer | Authenticated local member. |
| payment_customer_id, card_id | stored integer / nullable annotation | Supplied local references; no independent match/ownership proof. |
Read Stripe integration authorization guidance
Return authorization URLs or local connection guidance for live and test modes. This returns JSON; it does not redirect the browser, exchange a code or save connection credentials.
GET /api/v1/integrations/stripe/oauth
Before you call
Use the authorized administrator context for actor permissions, resource selection and base-key requirements.
Requires existing global stripe mode-specific app_client_id/auth_redirect_url and scopes/response_type configuration. All-four-field settings presence determines deauthorize, not a provider account check. The application owns callback correlation/authorization because the generated state is the resource public key and code exchange does not validate it.
Request
Bodyless; no mode parameter. Both modes are inspected. No collection/pagination.
Result
HTTP 200 status string ok with live/test objects.
| Field | Type / presence | Meaning |
|---|---|---|
| status | string | ok when the operation completes. |
| live, test | object | Independent connection guidance for each mode. |
| live.type, test.type | string | authorize when not all saved connection fields are present; deauthorize when access_token/refresh_token/stripe_user_id/stripe_publishable_key are all truthy. Not provider verification. |
| live.authorize_url, test.authorize_url | string | Empty for deauthorize; otherwise provider authorization URL with configured client_id, redirect_uri, scope, response_type and state equal to resource public key. It is not a random one-time CSRF state. |
Example: Inspect live and test connection guidance
Use existing admin context to inspect both modes. The example shows live authorization guidance and test local connection presence; no browser redirect happens.
curl -X GET "${WALLKIT_API_BASE}/api/v1/integrations/stripe/oauth" \
-H "token: ${ADMIN_TOKEN}" \
-H "resource: ${RESOURCE_KEY}"
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/integrations/stripe/oauth`, {
method: "GET",
headers: {token: process.env.ADMIN_TOKEN, resource: process.env.RESOURCE_KEY}
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/integrations/stripe/oauth",
method="GET", headers={"token": os.environ["ADMIN_TOKEN"],
"resource": os.environ["RESOURCE_KEY"]})
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 200 response excerpt:
{
"status": "ok",
"live": {
"type": "authorize",
"authorize_url": "https://example.com/SYNTHETIC_PROVIDER_AUTHORIZATION_URL"
},
"test": {
"type": "deauthorize",
"authorize_url": ""
}
}
Consequential alternate
The example URL is a synthetic placeholder, not the actual configured provider URL. test.deauthorize merely means four local connection values are present; it does not prove provider authorization is still active.
Recovery
| Status | Code / shape | Cause | Next action |
|---|---|---|---|
| 401/403 | access | Guest/user/non-granted role. | Use existing authorized admin context, not a member token or service-api-key. |
| 406 | stripe_generate_auth_url_fail | Operator/configuration failure. | Have integration administrator check resource/global Stripe mode and URL settings. |
Next task
Trusted application handles the existing provider authorization/callback flow, then exchanges its code. These examples never navigate the returned URL.
Exchange a Stripe integration authorization code
Exchange an existing provider callback code and attempt to save connected-account credentials in resource settings. This is integration configuration, not member login or payment.
POST /api/v1/integrations/stripe/oauth
Before you call
Use the authorized administrator context for actor permissions, resource selection and base-key requirements.
Existing callback handling must correlate authorized admin/resource/mode and supplied code. Handler does not accept/validate state or bind the code to an independently checked account owner.
Global mode-specific Wallkit Stripe private key is used for exchange.
If provider stripe_user_id exists, returned provider livemode selects the settings slot, which can differ from requested mode.
The entire resource settings array is saved with that stripe_connect slot replaced; save boolean is unchecked.
Provider exchange precedes local save: response success does not guarantee persisted credentials and an error does not make code replay safe.
Saving a resource can also clear that resource’s guest content-view records when default_guest_subscription_id exists but is false.
Request
JSON object required.
| Name | Location | Type / requirement | Meaning |
|---|---|---|---|
| code | JSON | required presence; trimmed string | Existing provider authorization code, not Wallkit member OAuth code/token or payment nonce. |
| mode | JSON | required presence; trimmed string | Exactly live or test, validated by operator. No implicit default on this action. |
Result
HTTP 200 only the following projection, not raw OAuth response.
| Field | Type / presence | Meaning |
|---|---|---|
| status | string | ok after exchange/settings save attempt. |
| mode | string | Requested sanitized mode, not proof of provider-selected persisted slot. |
| access_token, refresh_token | string / null | Provider integration credentials; stored attempt and echoed, keep private. Not member session/refresh credentials. |
| stripe_user_id | string / null | Provider connected account identifier; operator requires truthy value. |
| stripe_publishable_key | string / null | Provider key from exchange; no new credential issuance instructions. |
Example: Exchange an authorized test callback code
Use the existing trusted callback flow’s code and explicit test mode. The result echoes requested mode and private provider credentials; provider livemode selects the saved slot.
curl -X POST "${WALLKIT_API_BASE}/api/v1/integrations/stripe/oauth" \
-H "token: ${ADMIN_TOKEN}" \
-H "resource: ${RESOURCE_KEY}" \
-H "Content-Type: application/json" \
--data '{"code":"SYNTHETIC_PROVIDER_OAUTH_CODE","mode":"test"}'
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/integrations/stripe/oauth`, {
method: "POST",
headers: {token: process.env.ADMIN_TOKEN, resource: process.env.RESOURCE_KEY, "Content-Type": "application/json"},
body: JSON.stringify({"code":"SYNTHETIC_PROVIDER_OAUTH_CODE","mode":"test"})
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
body = {'code': 'SYNTHETIC_PROVIDER_OAUTH_CODE', 'mode': 'test'}
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/integrations/stripe/oauth",
method="POST", headers={"token": os.environ["ADMIN_TOKEN"],
"resource": os.environ["RESOURCE_KEY"], "Content-Type": "application/json"}, data=json.dumps(body).encode("utf-8"))
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 200 response excerpt:
{
"status": "ok",
"mode": "test",
"access_token": "SYNTHETIC_PRIVATE_PROVIDER_ACCESS_TOKEN",
"refresh_token": "SYNTHETIC_PRIVATE_PROVIDER_REFRESH_TOKEN",
"stripe_user_id": "acct_SYNTHETIC",
"stripe_publishable_key": "SYNTHETIC_PROVIDER_PUBLISHABLE_KEY"
}
Consequential alternate
HTTP 406 change_stripe_authorization_code_fail can follow a consumed provider code or attempted local settings write. Do not blindly replay the code. A success mode:test echoes request mode; provider livemode controls the actual saved slot.
Recovery
| Status | Code / shape | Cause | Next action |
|---|---|---|---|
| 406 | incorrect_data | Missing JSON. | Supply explicit code/mode JSON. |
| 409 | invalid_code / invalid_mode | Presence validation fails. | Supply callback code and exact configured mode. |
| 406 | change_stripe_authorization_code_fail | Invalid mode, exchange or settings failure. | Inspect intended resource/account/mode and current saved connection before choosing a new authorized callback flow. |
Next task
Read guidance for local all-fields presence, then use member source setup with configured account/mode. Guidance is not provider credential verification.
Clear Stripe connection settings and conditionally deauthorize
Clear the selected resource connection slot and conditionally call provider deauthorization. This is not member logout, source deletion, subscription cancellation or refund.
POST /api/v1/integrations/stripe/deauthorize
Before you call
Use the authorized administrator context for actor permissions, resource selection and base-key requirements.
Requires existing saved stripe_user_id for chosen mode and global mode_app_client_id.
The handler constructs a presence validator but does not run it; operator validation enforces live/test instead.
Provider deauthorization happens only when the selected resource’s partner has at most one resource with complete connection settings in that mode.
The count does not compare stripe_user_id values: another resource’s different connected account can suppress this provider call.
Local credentials are cleared regardless when that branch completes.
Provider call precedes unchecked resource save; no provider/local atomic rollback or replay promise.
Resource settings save can clear guest content-view records when default_guest_subscription_id exists but is false.
Request
JSON object required.
| Name | Location | Type / requirement | Meaning |
|---|---|---|---|
| mode | JSON | required trimmed string by operator | live or test. Missing/null becomes empty and fails operator validation; no effective default. |
Result
HTTP 200 status string ok; no provider response or saved settings projection. Selected stripe_connect mode slot is attempted replacement with access_token, refresh_token, stripe_user_id and stripe_publishable_key all null. Success does not prove provider authorization was revoked or local save persisted.
Example: Clear the test connection slot
Use existing admin context to clear the selected resource’s test connection. ok can mean local clearing while provider deauthorization is skipped by the partner-resource condition.
curl -X POST "${WALLKIT_API_BASE}/api/v1/integrations/stripe/deauthorize" \
-H "token: ${ADMIN_TOKEN}" \
-H "resource: ${RESOURCE_KEY}" \
-H "Content-Type: application/json" \
--data '{"mode":"test"}'
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/integrations/stripe/deauthorize`, {
method: "POST",
headers: {token: process.env.ADMIN_TOKEN, resource: process.env.RESOURCE_KEY, "Content-Type": "application/json"},
body: JSON.stringify({"mode":"test"})
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
body = {'mode': 'test'}
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/integrations/stripe/deauthorize",
method="POST", headers={"token": os.environ["ADMIN_TOKEN"],
"resource": os.environ["RESOURCE_KEY"], "Content-Type": "application/json"}, data=json.dumps(body).encode("utf-8"))
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 200 response excerpt:
{
"status": "ok"
}
Consequential alternate
If another partner resource has complete settings in that mode, HTTP 200 ok can mean local clearing without provider deauthorization. If selected local account ID is already empty, HTTP 406 stripe_deauthorize_connected_account_fail follows; no replay-safe success guarantee.
Recovery
| Status | Code / shape | Cause | Next action |
|---|---|---|---|
| 406 | incorrect_data | Missing JSON. | Send explicit mode object. |
| 406 | stripe_deauthorize_connected_account_fail | Invalid/missing mode, missing account/client config, provider or save exception. | Inspect selected resource settings and related partner connections before another deauthorization attempt. |
Next task
Read guidance to inspect local connection presence. Use member session/logout operations separately; this action does not end those sessions.