This post summarizes the iDEAL withdrawal routes that were briefly available around July–August 2026. Later, iDEAL significantly tightened its restrictions and began implementing a “one QR code per account” policy. I’m keeping a record here of the request and status changes I observed at the time.
Statement : This article draws on existing projects and link-extraction scripts from the open-source community. My contribution primarily involved integrating the link extraction process with the subsequent payment workflow. Since the relevant APIs and risk control rules are subject to change at any time, this document serves solely as a record of protocol research and troubleshooting.
1. The Difference Between iDEAL Direct Debit and Direct Card
1.1 Why is a chain pull necessary?
ChatGPT’s checkout uses Stripe. When the visitor’s IP address is located in a different region, the system displays payment methods available in that region, such as iDEAL in the Netherlands, UPI in India, and PIX in Brazil.
First, check the region where the IP address is located, and then have billing_details.country、billing_details.currency Ensure that the billing information matches that of the region. In a normal checkout response for a Dutch IP address,payment_method_types May include ideal。
The transaction did not bypass or force the payment method. The program only returns when Checkout has already returned ideal Continue creating the corresponding PaymentMethod, and from the subsequent requires_action Read the redirect URL from the bank’s checkout page in the status.
1.2 Comparison of Forks in the Direct Card and iDEAL Payment Chains
In automation solutions, “direct card linking” and “iDEAL chain withdrawal” are two completely different things:
| Dimension | Direct Card Linking Solution | iDEAL Chain Lifting Solution |
|---|---|---|
| Payment Methods Based On | Pre-deposited in the account and “Attached” pm_ Bank Card | A temporary, standalone instance created by this Checkout pm_ |
| User Interaction | The entire process is completed in the backend or within the account | It must be transferred to a third-party bank’s payment gateway. |
| Risk Control Critical Points | Extreme BIN (Card Issuer) Credit Checks and SetupIntent Authorization | End-to-End IP/TLS Fingerprint Consistency and Redirect Authenticity |
| Final Product | Complete the binding or payment directly | Obtain a Provider Redirect link that allows you to proceed to checkout |
flowchart TD
A["有效 Access Token (AT)"] --> B["创建对应区域的优惠 Checkout"]
B --> C["应用 Promotion 并校验最终金额"]
C --> D{"支付路径决策"}
subgraph DirectCard ["直卡分支"]
E1["读取已绑定的默认 pm_"] --> E2["创建 ConfirmationToken"]
E2 --> E3["Stripe 确认扣款"]
end
subgraph IdealExtract ["iDEAL 提链分支"]
F1["向 Stripe 创建 iDEAL pm_"] --> F2["向平台发起 Confirm 确认"]
F2 --> F3["捕获 requires_action 状态"]
F3 --> F4["提取 Provider Redirect URL"]
end
D -->|直卡| E1
D -->|iDEAL| F1
2. iDEAL Withdrawal Process
Based on the HAR packet capture from the browser at that time, the process from obtaining the user’s login session (AT) to obtaining the redirect link involves the following 9 steps:
1. Session 鉴权准备 → 获取并校验 Access Token
2. 创建 Checkout 会话 → 传入 country="NL", currency="EUR", checkout_ui_mode="custom"
3. 应用优惠 (Promotion) → 绑定试用优惠活动(如 0 元试用资格)
4. 税务与会话初始化 → 调用 Stripe payment_pages/init 或 elements/sessions
5. 前置状态核验 → 校验 payment_method_types 包含 ideal 并对齐金额
6. 创建 PaymentMethod → 向 Stripe 申请 type="ideal" 的临时 pm_
7. 确认支付 (Confirm) → 调用平台 /confirm 接口触发转交
8. 处理审批 (Approve) → 遇 requires_approval 时补充挑战凭证或等待上游放行
9. 提取跳转链接 → 从 requires_action.redirect_to_url 提取目标地址
sequenceDiagram
participant Worker as 自动化 Worker
participant OAI as OpenAI 账单服务
participant Stripe as Stripe 网关
participant Bank as iDEAL 银行网关
Worker->>OAI: POST /payments/checkout (NL/EUR, custom)
OAI-->>Worker: 返回 oaics_xxxx 与 publishable_key
Worker->>OAI: POST /payments/checkout/promotion (应用优惠)
Worker->>Stripe: POST /v1/payment_methods (type=ideal, bank=xxx)
Stripe-->>Worker: 返回 pm_ideal_xxxx
Worker->>OAI: POST /payments/checkout/confirm (带入 pm_)
OAI->>Stripe: 请求扣款/授权
Stripe-->>OAI: 返回 requires_action (redirect_to_url)
OAI-->>Worker: 返回包含 hooks.stripe.com/redirect 的跳转结构
Worker->>Worker: 解析并安全校验 Hostname
Worker-->>Bank: (交付给用户或进一步完成支付)
3. Checks to Perform Before Creating a PaymentMethod
If the intermediate state is not aligned, continuing with the request will only result in unusable objects. Therefore, before creating a `PaymentMethod`, you must first complete the following checks.
3.1 Checking for the Existence of a Checkout Session
After configuring the order creation API, you must obtain oaics_... A session ID in the specified format and a Stripe Publishable Key. If you only have a regular Hosted web link and not the underlying session ID, you won’t be able to call the underlying API later on.
3.2 Payment Method Verification
Just because Stripe supports iDEAL doesn’t mean that every Checkout—in every region and for every visiting IP address—will return it. The code needs to check for this. payment_method_types Included or Not "ideal"; If not, stop the current task and do not attempt to add or enable it yourself.
3.3 Billing Snapshots and Amount-Based Access Control
If you’re participating in a “zero-yuan trial” promotion, you’ll need to verify the final amount separately:
- A successful response from the discount API doesn’t count; you must read the data in the Checkout Snapshot again.
amount_total; - When the target is a free trial, the final amount due must be exactly 0; if it is a top-up at the regular price, the amount must also exactly match the listed price;
- If the amount does not match (for example, if it reverts to the original price of 20 euros), stop the confirmation immediately.
4. Create a PaymentMethod and handle the confirmation status
Only after all the preliminary checks have been passed will the program request Stripe to create an iDEAL PaymentMethod for this order.
4.1 Single-Instance Constraint for `PaymentMethod`
iDEAL’s pm_ It is a one-time token and can only be bound to the current checkout. If this round fails midway, the token generated in the previous round pm_ It must be thrown away immediately; under no circumstances should it be reused for the next order.
4.2 Several States After Confirmation
Call the platform’s /confirm After that, the response typically falls into one of the following three categories:
- Back
requires_action, including those withredirect_to_url, you can continue extracting URLs; - Back
requires_approval, you will need to top up your Sentinel Tokens with Turnstile PoW proof of computing power, or wait for the platform to process this asynchronously; - Stripe or the upstream bank is still
processing...requires short-cycle status polling.
flowchart TD
A["POST /checkout/confirm"] --> B{"解析当前响应状态"}
B -->|含有 redirect_to_url| C["提取并验证 Redirect URL"]
B -->|requires_approval| D["触发 Sentinel / Turnstile 凭证审批"]
D --> E["短周期轮询 Checkout 状态"]
B -->|processing / pending| E
E -->|成功生成跳转| C
E -->|超时 / 拒单 / 状态失效| F["标记失败并优雅退出"]
C --> G["输出 provider_link_ready"]
5. Network and Redirect Checks
In automation processes, changes to network gateways and incorrect redirect addresses are the most common causes of failure.
5.1 End-to-End IP and TLS Fingerprint Consistency
From order creation, initialization, and creation pm_ At the end, when you confirm, the entire link should remain The Same Outbound IP Address With the same set of TLS fingerprints (for example, using curl_cffi (Fixed version of Chrome or Safari). If you create an order using Proxy A and then switch to Proxy B to confirm it, you may receive invalid_request_error Or decline the order.
5.2 Security Validation for Redirect Domains
Once you have the URL, you can’t just perform a string search (for example, url.includes("ideal.nl")). Both open redirects and domain spoofing can be detected using this method:
https://ideal.nl.attacker.invalid/pay
https://phishing-site.example/?redirect=https://ideal.nl
The program should use a standard URL parsing library to extract the hostname and then compare it against the whitelist. Only allow traffic from Stripe’s official redirect domains (such as hooks.stripe.com) and trusted bank gateway domain names; all other addresses are discarded.
6. Record the withdrawal and payment separately
In the tool, “Withdraw” and “Pay” can be divided into two states:
{
"jobId": "ideal_task_98234",
"extractionStatus": "provider_link_ready",
"paymentStatus": "awaiting_payment",
"expiresAt": "2026-08-20T00:25:00Z"
}
provider_link_ready: I have obtained a payment link from the standard confirmation results;awaiting_payment: This means the payment hasn’t been processed yet, and you still need to wait for the person to actually scan the QR code or authorize the transaction on the bank’s webpage.
After separating the logs, link generation and actual payment can each handle timeouts and retries independently.
Is this route still available?
This log primarily tracks the sequence of states between Stripe Checkout, PaymentMethod, Confirm, and Redirect.
Payment risk control is constantly evolving. With payment methods like iDEAL, which do not involve card binding or card headers, you need to check whether the payment method is available, whether the IP and TLS fingerprints remain consistent throughout the entire process, and the status after confirmation. Receiving a redirect link does not mean the payment is complete; you must still complete authorization on the bank’s page and confirm the payment result. This post primarily documents the sequence of requests at the time to facilitate future troubleshooting.

