[{"data":1,"prerenderedAt":247},["ShallowReactive",2],{"content-\u002Fprompts\u002Fbuild-a-neobank":3,"prompts-category-integrations":161},{"id":4,"title":5,"authors":6,"body":7,"categories":6,"category":142,"categoryType":6,"compare":6,"contributors":6,"date":143,"description":144,"extension":145,"faq":6,"howto":6,"isBlog":146,"isChangelog":146,"meta":147,"navigation":148,"path":149,"pillar":146,"products":150,"rawbody":156,"role":6,"seo":157,"seoTitle":158,"standalone":148,"stem":159,"thumbnail":6,"translationOf":6,"updated":6,"__hash__":160},"content\u002Fprompts\u002Fbuild-a-neobank.md","Build a neobank",null,{"type":8,"value":9,"toc":136},"minimark",[10,14,19,30,34,81,87,91],[11,12,13],"p",{},"Paste this prompt into a coding agent running in an empty folder, then walk away. It builds the app, tests every money flow against your development instance, and talks to you once, at the end, with the app open in your browser and a demo script.",[15,16,18],"h2",{"id":17},"prompt","Prompt",[20,21,27],"pre",{"className":22,"code":24,"language":25,"meta":26},[23],"language-text","Build a working neobank on BlindPay in this folder, unattended, and prove it works.\n\nYou are a senior fintech engineer. Build first, speak last: no questions, no plan for approval, no \"should I continue\". Every decision is either settled below or yours to make. When something is unclear, pick the option that keeps the app working, note it for the final report, and keep going. The person who started you will look at the screen only when you finish, so the deliverable is a running app plus proof that every flow works. You address them once, in the final report.\n\n## The product\n\nA dollar account for people who live in the US and move money to and from Latin America. A new user opens an account in about a minute, gets a USD balance with US bank details and a Mexican CLABE, adds money, pays family in Brazil over Pix or in Mexico over SPEI, pays a friend in the app instantly, and watches every movement settle.\n\nName: if a name was given after this prompt, use it. Otherwise invent a short, original name that is not an existing bank or fintech, plus a simple wordmark.\n\nBlindPay is the money layer: terms of service, KYC, custody in BlindPay-managed wallets, virtual accounts, payins, payouts, and wallet-to-wallet transfers. It all runs on a BlindPay development instance, where the test stablecoin USDB stands in for USDC, KYC approves itself, and no real money moves. The app shows a \"Sandbox\" badge so nobody mistakes it for real money.\n\nBuild only what this prompt lists. Cards, savings, yield, investing, crypto trading, and loans are out of scope for this build, so they get no screens and no placeholders.\n\n## Credentials\n\nRead BLINDPAY_API_KEY and BLINDPAY_INSTANCE_ID from the environment or from a .env file in this folder. Never print, log, or commit the key: check that it is set without echoing it, and keep .env in .gitignore. Call GET https:\u002F\u002Fapi.blindpay.com\u002Fv1\u002Finstances\u002F{instance_id} first. The type must be \"development\". If it is \"production\", stop and say so: this build creates customers and moves money without asking.\n\nIf a value is missing, still build everything and run every check that needs no API call. Then ask once, as your final message: create a development instance and an API key at https:\u002F\u002Fapp.blindpay.com, add BLINDPAY_API_KEY and BLINDPAY_INSTANCE_ID to .env, and reply. When they do, run the verification below and send the final report.\n\n## Settled decisions\n\n- Stack: Next.js with the App Router, TypeScript in strict mode, Tailwind CSS, npm, Node 20 or newer. One process serves the pages and the API routes. No UI kit; lucide-react icons are fine.\n- Folder: build in this folder. If it already holds a project (anything besides .env and dotfiles), build in a new subfolder named after the app and copy .env into it. create-next-app refuses a folder that contains .env, so scaffold in a temporary folder and move the files in, or write the config files by hand.\n- Port: 3456, or PORT if set. If the port is busy, take the next free one. Build every redirect URL from the incoming request's origin, so a port change never breaks one.\n- Processes: stop only processes you started, by the PID you saved when you started them. Never kill by name, pattern, or port: other apps on this machine may match.\n- Storage: one JSON file at .data\u002Fdb.json behind a small module with an in-process lock and atomic writes (write a temp file, then rename). No database server, no native modules. .data\u002F is gitignored.\n- Auth: sign up with name and email, sign in with email, session in a signed httpOnly cookie. Generate SESSION_SECRET once into .env. Call it demo auth in the README.\n- BlindPay access: plain fetch from one server-only module, with cache: \"no-store\" (you keep your own short cache, below). The key never reaches the browser; the browser only talks to the app's API routes.\n- Network base_sepolia and token USDB for every wallet, quote, payin, payout, and transfer.\n- Money: integer cents everywhere in the app, formatted with Intl.NumberFormat. No floating point math on amounts.\n- Updates: polling, no webhooks. BlindPay cannot reach localhost, and a tunnel is one more thing to break.\n- Git: initialize a repository and commit once everything passes. Write a README with setup, a short architecture note, and the demo script.\n\n## What to build\n\n1. Landing: the name, one line on what it does, \"Open an account\", \"Sign in\".\n2. Onboarding: sign up (name, email), then terms of service, then identity, then account ready.\n   - Terms: create a BlindPay terms link, send the browser to it, and receive the tos_id back on \u002Fonboarding\u002Fterms.\n   - Identity: a KYC form prefilled with the sandbox profile below (name and email from sign-up, every field editable, sample document images as thumbnails). Submitting creates the BlindPay customer, then shows \"Verifying\" until kyc_status is approved. A rejected status gets its own clear screen.\n   - Account ready: create the managed wallet, the US virtual account, and the Mexican CLABE, then show them with a short celebration.\n3. Home: the USD balance, large. An account details card with the US routing and account numbers (ACH and wire) and the CLABE, each with a copy button. Buttons for Add money and Send. Recent activity.\n4. Add money:\n   - From Mexico: the CLABE, plus a sandbox button \"Simulate a SPEI transfer\" with an MXN amount (default 5,000.00) and a sender name. The money lands in seconds at the live rate. This is the best moment of the demo, so make it feel good: after the click, watch for the new payin and animate the balance when it lands.\n   - By Pix: a BRL amount, a quote showing the USD that will land, then the payin with its Pix code and a copy button. On development it completes by itself in about 30 seconds.\n   - From a US bank: the routing and account numbers, shown as deposit instructions with a copy button and no simulate button.\n5. Send to a bank account: choose Brazil (Pix), Mexico (SPEI), or United States (ACH); fill a form generated from the bank-details endpoint; save the recipient; enter a USD amount; show the quote (what the recipient gets in their currency, fee, rate, a countdown to expiry); confirm; follow the payout to completed. Saved recipients can be reused.\n6. Send to a friend: pick another user of the app by email, enter a USD amount, confirm. It settles in seconds and both balances change.\n7. Activity: every payin, payout, and transfer with direction, counterparty, amount in USD and local currency, rail, and a status chip (processing, completed, failed, refunded). Tapping a row opens details with the BlindPay IDs and timestamps.\n8. Failure paths: on development a $777.00 payout is refunded and a $666.00 payout fails. Refunded copy says the money is back in the balance. Failed copy says the payout did not go through and never claims the money came back, because on development it does not.\n\nDesign: it must look like a consumer fintech app you would show investors. Mobile-first single column, about 440px wide and centered on desktop, generous spacing, one accent color, Inter or the system font, large tabular numerals for money, country flags, skeletons while loading, toasts after actions, and buttons that show progress and never submit twice.\n\n## BlindPay facts, verified on a development instance\n\nBase URL https:\u002F\u002Fapi.blindpay.com\u002Fv1 with the header Authorization: Bearer \u003Ckey>. Reference: https:\u002F\u002Fblindpay.com\u002Fdocs\u002Fllms.txt and the OpenAPI spec at https:\u002F\u002Fapi.blindpay.com\u002Fdoc. These facts were checked against the live API. If a response disagrees, trust the response, adapt, and list the difference in the final report.\n\n- Rate limit: a development instance takes about 40 requests per minute. Past that you get 429 development_instance_rate_limit_exceeded with a Retry-After header. Cache GET responses per user on the server for 10 seconds, poll only while something is pending (every 5 seconds against your own API, which serves from that cache), never fire more than 4 BlindPay calls for one page load, and on a 429 wait Retry-After and retry once while showing cached data.\n- Terms: POST \u002Fe\u002Finstances\u002F{instance_id}\u002Ftos with {\"idempotency_key\": \"\u003Cnew uuid>\", \"redirect_url\": \"\u003Corigin>\u002Fonboarding\u002Fterms\"} returns {\"url\"}. The page behind it has one Accept button. After Accept, BlindPay sends the browser to redirect_url + \"?tos_id=to_...\". It appends \"?tos_id=\" without looking for an existing query string, so redirect_url must not have one: keep sign-up state in the session, and if the query parse fails, find to_[A-Za-z0-9]+ in the full URL.\n- Customer: POST \u002Finstances\u002F{instance_id}\u002Fcustomers with the tos_id and this sandbox profile (it passes; keep the image URLs as they are): {\"type\": \"individual\", \"kyc_type\": \"standard\", \"first_name\": \"\u003Cfrom sign-up>\", \"last_name\": \"\u003Cfrom sign-up>\", \"email\": \"\u003Cfrom sign-up>\", \"date_of_birth\": \"1994-05-12T00:00:00Z\", \"tax_id\": \"12345678\", \"phone_number\": \"+13022006100\", \"address_line_1\": \"8 The Green\", \"address_line_2\": \"#12345\", \"city\": \"Dover\", \"state_province_region\": \"DE\", \"country\": \"US\", \"postal_code\": \"02050\", \"ip_address\": \"127.0.0.1\", \"id_doc_country\": \"US\", \"id_doc_type\": \"PASSPORT\", \"id_doc_front_file\": \"https:\u002F\u002Fplacehold.co\u002F800x1000.jpg\", \"selfie_file\": \"https:\u002F\u002Fplacehold.co\u002F800x1000.jpg\", \"proof_of_address_doc_type\": \"UTILITY_BILL\", \"proof_of_address_doc_file\": \"https:\u002F\u002Fplacehold.co\u002F800x1000.jpg\"}. BlindPay downloads every document URL: data: URIs are rejected and dead links fail with FILES_UNREADABLE. The response is only {\"id\", \"customer_id\"}; GET \u002Finstances\u002F{instance_id}\u002Fcustomers\u002F{id} shows kyc_status, which reached approved within 5 seconds in testing. A first name of \"Fail\" forces a rejection.\n- Wallet: POST \u002Finstances\u002F{instance_id}\u002Fcustomers\u002F{customer_id}\u002Fwallets with {\"network\": \"base_sepolia\", \"name\": \"Main account\", \"external_id\": \"\u003Cyour user id>\"} returns id (bl_...) and address. Store both. GET \u002Finstances\u002F{instance_id}\u002Fcustomers\u002F{customer_id}\u002Fwallets\u002F{wallet_id}\u002Fbalance returns one entry per token, like {\"USDB\": {\"amount\": 106.64}, \"USDC\": {...}}. amount is in whole tokens, so cents = Math.round(amount * 100). This endpoint is the balance; never compute it from transactions.\n- US account: POST \u002Finstances\u002F{instance_id}\u002Fcustomers\u002F{customer_id}\u002Fvirtual-accounts with {\"banking_partner\": \"jpmorgan\", \"token\": \"USDB\", \"blockchain_wallet_id\": \"\u003Cthe bl_ wallet id>\"}. The field is named blockchain_wallet_id but takes the managed wallet id. On development it comes back approved at once; us.ach and us.wire hold routing_number (always 110000000 on development) and account_number. Bank names and addresses come back as the literal \"\u003Cdevelopment>\" there, so hide any field with that value.\n- Mexican CLABE: the same call with \"banking_partner\": \"spei\" returns mx.spei.clabe and mx.beneficiary.name. A customer gets one account per banking partner, so create each once, store it, and never recreate it on a page load.\n- Simulated SPEI deposit (development only): POST \u002Finstances\u002F{instance_id}\u002Fcustomers\u002F{customer_id}\u002Fvirtual-accounts\u002F{virtual_account_id}\u002Fsimulate-spei-deposit with {\"amount\": \u003CMXN cents>, \"sender_name\": \"Juan Perez\"} returns {\"success\": true}. Within about 10 seconds a completed payin with payment_method \"spei\" shows up in GET \u002Finstances\u002F{instance_id}\u002Fpayins?customer_id=\u003Cid>&limit=10 and the balance rises. The sender's name is in the payin's tracking_transaction.sender_name. MXN 2,000.00 delivered 106.64 USDB in testing.\n- Payin by Pix: POST \u002Finstances\u002F{instance_id}\u002Fpayin-quotes with {\"wallet_id\": \"\u003Cbl_>\", \"currency_type\": \"sender\", \"cover_fees\": true, \"request_amount\": \u003CBRL cents, at least 1000>, \"payment_method\": \"pix\", \"token\": \"USDB\"}. No network field: the wallet decides it. With cover_fees true the fee is added to what the payer sends, so show the quote's sender_amount as the amount to pay and sender_amount minus request_amount as the fee (R$500.00 became R$501.00 in testing, while flat_fee said R$0.10). Within 5 minutes, POST \u002Finstances\u002F{instance_id}\u002Fpayins\u002Fevm with {\"payin_quote_id\": \"\u003Cid>\"} (this endpoint serves every rail). The payin has pix_code, which is the literal string \"\u003Cdevelopment>\" on development, so show a sandbox note instead of a QR code. It completes by itself about 30 seconds later.\n- Recipients: POST \u002Finstances\u002F{instance_id}\u002Fcustomers\u002F{customer_id}\u002Fbank-accounts. The rails are pix, spei_bitso (Mexico: the payin payment_method is spei, but the bank account type is spei_bitso), and ach. GET \u002Favailable\u002Fbank-details?rail=\u003Crail> returns each field's key, label, required, regex, and choices under items (each with label, value, and sometimes is_active); build the forms from it. Pix needs only {\"type\": \"pix\", \"name\", \"pix_key\"}; bank-details lists only pix_key, so name is your own field. SPEI needs spei_protocol \"clabe\", spei_clabe (18 digits with a check digit; 012180001234567899 is valid for tests), and beneficiary_name. ACH needs beneficiary_name, routing_number (021000021 works for tests), account_number, account_type (checking or saving), account_class (individual), recipient_relationship (for example family), address_line_1, city, state_province_region, country, and postal_code.\n- Payout: POST \u002Finstances\u002F{instance_id}\u002Fquotes with {\"bank_account_id\": \"\u003Cba_>\", \"currency_type\": \"sender\", \"cover_fees\": false, \"request_amount\": \u003CUSD cents, at least 500>, \"network\": \"base_sepolia\", \"token\": \"USDB\"} returns sender_amount, receiver_amount (cents of the recipient's currency), flat_fee, and expires_at (epoch milliseconds, 5 minutes out). Ignore the contract field: it is for wallets the customer signs for. The quotation fields are scaled by 100 (an ACH quote returns 100 for a 1.00 rate), so show the rate as receiver_amount \u002F sender_amount instead. Then POST \u002Finstances\u002F{instance_id}\u002Fpayouts\u002Fevm with {\"quote_id\": \"\u003Cqu_>\", \"sender_wallet_address\": \"\u003Cmanaged wallet address>\"}: a managed wallet needs no signature or approval step. It goes from processing to completed within seconds on development. A request_amount of 77700 ends refunded about 15 seconds later, with the USDB back in the wallet (it also appears as a wallet deposit). A request_amount of 66600 ends failed, and the USDB that left the wallet stays out on development.\n- Friend transfer: POST \u002Finstances\u002F{instance_id}\u002Ftransfer-quotes with {\"wallet_id\": \"\u003Csender bl_>\", \"amount_reference\": \"sender\", \"request_amount\": \u003CUSD cents>, \"sender_token\": \"USDB\", \"customer_wallet_address\": \"\u003Crecipient wallet address>\", \"customer_token\": \"USDB\", \"customer_network\": \"base_sepolia\", \"cover_fees\": true}, then right away POST \u002Finstances\u002F{instance_id}\u002Ftransfers with {\"transfer_quote_id\": \"\u003Cid>\"}. The quote id starts with qu_ (some docs say pq_). It completed in about 5 seconds in testing. Test transfers with ordinary amounts: 66600 and 77700 are for payins and payouts.\n- Lists: GET \u002Finstances\u002F{instance_id}\u002Fpayins, \u002Fpayouts, and \u002Ftransfers filter by customer_id and return {\"data\": [...], \"pagination\": {...}} when you pass limit, which must be 10, 50, 100, 200, 500, or 1000 (anything else is a 400). A customer's wallets, virtual accounts, and bank accounts come back as plain arrays.\n- Activity feed: GET ...\u002Fwallets\u002F{wallet_id}\u002Fdeposits lists every inbound movement, payin settlements included, so adding it to payins double counts. A friend transfer shows up for the receiver only there. Record both sides of every friend transfer in your own store when you create it, refresh its status with GET \u002Finstances\u002F{instance_id}\u002Ftransfers\u002F{id}, and build the feed from payins, payouts, and those records.\n- Idempotency: send an Idempotency-Key header with a fresh UUID per user action on every POST that creates a customer, quote, payin, payout, or transfer. Reuse it only to retry that same action.\n- ID prefixes: customer re_, wallet bl_, virtual account va_, bank account ba_, quote qu_, payin pi_, payout po_, transfer tr_, terms to_.\n\n## Verify before you report\n\n1. npm run build passes with no type errors, and lint passes if the scaffold set it up.\n2. Vitest unit tests cover the money helpers and the BlindPay client (error mapping, 429 retry), with fetch mocked.\n3. Run the production build (npm start on the chosen port) in the background, logging to .data\u002Fserver.log.\n4. Install @playwright\u002Ftest with Chromium and write tests\u002Fe2e\u002Fdemo.spec.ts. It drives the real UI against the development instance, one step at a time, and saves a full-page screenshot of every screen to screenshots\u002F:\n   a. Sign up Maria Santos with a unique email (maria+\u003Ctimestamp>@example.com), wait for the BlindPay terms page (https:\u002F\u002Fapp.blindpay.com\u002Fe\u002Fterms-of-service), click the button named exactly \"Accept\" (the page also has a hidden \"Accepted\" button), wait until the URL is back on your own host at \u002Fonboarding\u002Fterms (BlindPay's own URL contains your redirect_url, so a path match alone fires too early), submit identity, and wait for the account to be ready.\n   b. Simulate a SPEI transfer of MXN 20,000.00 and wait for the balance to rise. That funds the failure tests in step f.\n   c. Deposit R$ 500.00 by Pix and wait for completed.\n   d. Add a Brazil Pix recipient and send $50.00; wait for completed. Add a Mexico SPEI recipient and send $25.00; wait for completed.\n   e. Sign up Lucas Almeida the same way. As Maria, send Lucas $20.00 and check both balances.\n   f. As Maria, send $777.00 to the Pix recipient and check that it shows as refunded and the balance comes back. Then send $666.00 and check that it shows as failed.\n   Settlement waits get up to 2 minutes each. Let the app's polling do the work and keep the pace under the rate limit. If you run the spec in the background, wait for it to finish: a status line while you wait is fine, a question is not.\n5. Fix what fails and rerun until the whole spec passes. If one step still fails after three real attempts, leave the rest working and report that step as broken, with the error.\n6. Leave the app running on its port and open it in the default browser (open on macOS, xdg-open on Linux, start on Windows).\n\n## Final report\n\nThis is your only message. Plain text, short, in this order:\n1. The URL, and the email to sign in with (Maria from the test run, already funded and with history).\n2. A 60-second demo script: what to click and what appears.\n3. What was verified, with the BlindPay IDs created and the final balances.\n4. Where the screenshots are.\n5. How to start it again.\n6. What changes for production: a production instance and key, USDC or USDT on a mainnet network, real document upload (POST \u002Fv1\u002Fupload), real authentication, webhooks with signature verification instead of polling, and removing the sandbox buttons.\n7. Every place the live API disagreed with this prompt.\n","text","",[28,29,24],"code",{"__ignoreMap":26},[15,31,33],{"id":32},"how-to-use","How to use",[35,36,37,54,69,75,78],"ol",{},[38,39,40,41,48,49,53],"li",{},"Sign up at ",[42,43,47],"a",{"href":44,"rel":45},"https:\u002F\u002Fapp.blindpay.com",[46],"nofollow","app.blindpay.com",", create a development instance, and create an API key in its ",[50,51,52],"strong",{},"API Keys"," tab.",[38,55,56,57,60,61,64,65,68],{},"In an empty folder, create a ",[28,58,59],{},".env"," file with ",[28,62,63],{},"BLINDPAY_API_KEY=..."," and ",[28,66,67],{},"BLINDPAY_INSTANCE_ID=in_...",".",[38,70,71,72,68],{},"Start your agent with permission prompts off, or it will stop to ask before every command. In Claude Code: ",[28,73,74],{},"claude --dangerously-skip-permissions",[38,76,77],{},"Paste the prompt. To pick the name, add one line after it, like \"Call it Pampa\".",[38,79,80],{},"Come back in about 30 minutes. The app opens in your browser with a funded test account and a demo script.",[11,82,83,84,86],{},"No ",[28,85,59],{},"? The agent still builds everything and asks for the two values once, at the end.",[15,88,90],{"id":89},"related-docs","Related docs",[92,93,94,101,108,115,122,129],"ul",{},[38,95,96],{},[42,97,100],{"href":98,"rel":99},"https:\u002F\u002Fblindpay.com\u002Fdocs\u002Flearn\u002Fsandbox-vs-production",[46],"Sandbox vs. production",[38,102,103],{},[42,104,107],{"href":105,"rel":106},"https:\u002F\u002Fblindpay.com\u002Fdocs\u002Fwallets",[46],"Managed wallets",[38,109,110],{},[42,111,114],{"href":112,"rel":113},"https:\u002F\u002Fblindpay.com\u002Fdocs\u002Fvirtual-accounts",[46],"Virtual accounts",[38,116,117],{},[42,118,121],{"href":119,"rel":120},"https:\u002F\u002Fblindpay.com\u002Fdocs\u002Fpayin-quotes",[46],"Payin quotes",[38,123,124],{},[42,125,128],{"href":126,"rel":127},"https:\u002F\u002Fblindpay.com\u002Fdocs\u002Fpayout-quotes",[46],"Payout quotes",[38,130,131],{},[42,132,135],{"href":133,"rel":134},"https:\u002F\u002Fblindpay.com\u002Fdocs\u002Ftransfers",[46],"Transfers",{"title":26,"searchDepth":137,"depth":137,"links":138},2,[139,140,141],{"id":17,"depth":137,"text":18},{"id":32,"depth":137,"text":33},{"id":89,"depth":137,"text":90},"integrations","2026-10-29","One prompt, no questions: your coding agent builds and tests a working neobank on a BlindPay development instance, with KYC, US account details, a Mexican CLABE, Pix deposits, payouts, and instant transfers between users.","md",false,{},true,"\u002Fprompts\u002Fbuild-a-neobank",[151,152,153,154,155],"payins","payouts","virtual-accounts","compliance","quotes","---\ntitle: \"Build a neobank\"\nseoTitle: \"Build a neobank on BlindPay with one AI agent prompt\"\ndescription: \"One prompt, no questions: your coding agent builds and tests a working neobank on a BlindPay development instance, with KYC, US account details, a Mexican CLABE, Pix deposits, payouts, and instant transfers between users.\"\ndate: \"2026-10-29\"\ncategory: \"integrations\"\nproducts: [\"payins\", \"payouts\", \"virtual-accounts\", \"compliance\", \"quotes\"]\nstandalone: true\n---\n\nPaste this prompt into a coding agent running in an empty folder, then walk away. It builds the app, tests every money flow against your development instance, and talks to you once, at the end, with the app open in your browser and a demo script.\n\n## Prompt\n\n```text\nBuild a working neobank on BlindPay in this folder, unattended, and prove it works.\n\nYou are a senior fintech engineer. Build first, speak last: no questions, no plan for approval, no \"should I continue\". Every decision is either settled below or yours to make. When something is unclear, pick the option that keeps the app working, note it for the final report, and keep going. The person who started you will look at the screen only when you finish, so the deliverable is a running app plus proof that every flow works. You address them once, in the final report.\n\n## The product\n\nA dollar account for people who live in the US and move money to and from Latin America. A new user opens an account in about a minute, gets a USD balance with US bank details and a Mexican CLABE, adds money, pays family in Brazil over Pix or in Mexico over SPEI, pays a friend in the app instantly, and watches every movement settle.\n\nName: if a name was given after this prompt, use it. Otherwise invent a short, original name that is not an existing bank or fintech, plus a simple wordmark.\n\nBlindPay is the money layer: terms of service, KYC, custody in BlindPay-managed wallets, virtual accounts, payins, payouts, and wallet-to-wallet transfers. It all runs on a BlindPay development instance, where the test stablecoin USDB stands in for USDC, KYC approves itself, and no real money moves. The app shows a \"Sandbox\" badge so nobody mistakes it for real money.\n\nBuild only what this prompt lists. Cards, savings, yield, investing, crypto trading, and loans are out of scope for this build, so they get no screens and no placeholders.\n\n## Credentials\n\nRead BLINDPAY_API_KEY and BLINDPAY_INSTANCE_ID from the environment or from a .env file in this folder. Never print, log, or commit the key: check that it is set without echoing it, and keep .env in .gitignore. Call GET https:\u002F\u002Fapi.blindpay.com\u002Fv1\u002Finstances\u002F{instance_id} first. The type must be \"development\". If it is \"production\", stop and say so: this build creates customers and moves money without asking.\n\nIf a value is missing, still build everything and run every check that needs no API call. Then ask once, as your final message: create a development instance and an API key at https:\u002F\u002Fapp.blindpay.com, add BLINDPAY_API_KEY and BLINDPAY_INSTANCE_ID to .env, and reply. When they do, run the verification below and send the final report.\n\n## Settled decisions\n\n- Stack: Next.js with the App Router, TypeScript in strict mode, Tailwind CSS, npm, Node 20 or newer. One process serves the pages and the API routes. No UI kit; lucide-react icons are fine.\n- Folder: build in this folder. If it already holds a project (anything besides .env and dotfiles), build in a new subfolder named after the app and copy .env into it. create-next-app refuses a folder that contains .env, so scaffold in a temporary folder and move the files in, or write the config files by hand.\n- Port: 3456, or PORT if set. If the port is busy, take the next free one. Build every redirect URL from the incoming request's origin, so a port change never breaks one.\n- Processes: stop only processes you started, by the PID you saved when you started them. Never kill by name, pattern, or port: other apps on this machine may match.\n- Storage: one JSON file at .data\u002Fdb.json behind a small module with an in-process lock and atomic writes (write a temp file, then rename). No database server, no native modules. .data\u002F is gitignored.\n- Auth: sign up with name and email, sign in with email, session in a signed httpOnly cookie. Generate SESSION_SECRET once into .env. Call it demo auth in the README.\n- BlindPay access: plain fetch from one server-only module, with cache: \"no-store\" (you keep your own short cache, below). The key never reaches the browser; the browser only talks to the app's API routes.\n- Network base_sepolia and token USDB for every wallet, quote, payin, payout, and transfer.\n- Money: integer cents everywhere in the app, formatted with Intl.NumberFormat. No floating point math on amounts.\n- Updates: polling, no webhooks. BlindPay cannot reach localhost, and a tunnel is one more thing to break.\n- Git: initialize a repository and commit once everything passes. Write a README with setup, a short architecture note, and the demo script.\n\n## What to build\n\n1. Landing: the name, one line on what it does, \"Open an account\", \"Sign in\".\n2. Onboarding: sign up (name, email), then terms of service, then identity, then account ready.\n   - Terms: create a BlindPay terms link, send the browser to it, and receive the tos_id back on \u002Fonboarding\u002Fterms.\n   - Identity: a KYC form prefilled with the sandbox profile below (name and email from sign-up, every field editable, sample document images as thumbnails). Submitting creates the BlindPay customer, then shows \"Verifying\" until kyc_status is approved. A rejected status gets its own clear screen.\n   - Account ready: create the managed wallet, the US virtual account, and the Mexican CLABE, then show them with a short celebration.\n3. Home: the USD balance, large. An account details card with the US routing and account numbers (ACH and wire) and the CLABE, each with a copy button. Buttons for Add money and Send. Recent activity.\n4. Add money:\n   - From Mexico: the CLABE, plus a sandbox button \"Simulate a SPEI transfer\" with an MXN amount (default 5,000.00) and a sender name. The money lands in seconds at the live rate. This is the best moment of the demo, so make it feel good: after the click, watch for the new payin and animate the balance when it lands.\n   - By Pix: a BRL amount, a quote showing the USD that will land, then the payin with its Pix code and a copy button. On development it completes by itself in about 30 seconds.\n   - From a US bank: the routing and account numbers, shown as deposit instructions with a copy button and no simulate button.\n5. Send to a bank account: choose Brazil (Pix), Mexico (SPEI), or United States (ACH); fill a form generated from the bank-details endpoint; save the recipient; enter a USD amount; show the quote (what the recipient gets in their currency, fee, rate, a countdown to expiry); confirm; follow the payout to completed. Saved recipients can be reused.\n6. Send to a friend: pick another user of the app by email, enter a USD amount, confirm. It settles in seconds and both balances change.\n7. Activity: every payin, payout, and transfer with direction, counterparty, amount in USD and local currency, rail, and a status chip (processing, completed, failed, refunded). Tapping a row opens details with the BlindPay IDs and timestamps.\n8. Failure paths: on development a $777.00 payout is refunded and a $666.00 payout fails. Refunded copy says the money is back in the balance. Failed copy says the payout did not go through and never claims the money came back, because on development it does not.\n\nDesign: it must look like a consumer fintech app you would show investors. Mobile-first single column, about 440px wide and centered on desktop, generous spacing, one accent color, Inter or the system font, large tabular numerals for money, country flags, skeletons while loading, toasts after actions, and buttons that show progress and never submit twice.\n\n## BlindPay facts, verified on a development instance\n\nBase URL https:\u002F\u002Fapi.blindpay.com\u002Fv1 with the header Authorization: Bearer \u003Ckey>. Reference: https:\u002F\u002Fblindpay.com\u002Fdocs\u002Fllms.txt and the OpenAPI spec at https:\u002F\u002Fapi.blindpay.com\u002Fdoc. These facts were checked against the live API. If a response disagrees, trust the response, adapt, and list the difference in the final report.\n\n- Rate limit: a development instance takes about 40 requests per minute. Past that you get 429 development_instance_rate_limit_exceeded with a Retry-After header. Cache GET responses per user on the server for 10 seconds, poll only while something is pending (every 5 seconds against your own API, which serves from that cache), never fire more than 4 BlindPay calls for one page load, and on a 429 wait Retry-After and retry once while showing cached data.\n- Terms: POST \u002Fe\u002Finstances\u002F{instance_id}\u002Ftos with {\"idempotency_key\": \"\u003Cnew uuid>\", \"redirect_url\": \"\u003Corigin>\u002Fonboarding\u002Fterms\"} returns {\"url\"}. The page behind it has one Accept button. After Accept, BlindPay sends the browser to redirect_url + \"?tos_id=to_...\". It appends \"?tos_id=\" without looking for an existing query string, so redirect_url must not have one: keep sign-up state in the session, and if the query parse fails, find to_[A-Za-z0-9]+ in the full URL.\n- Customer: POST \u002Finstances\u002F{instance_id}\u002Fcustomers with the tos_id and this sandbox profile (it passes; keep the image URLs as they are): {\"type\": \"individual\", \"kyc_type\": \"standard\", \"first_name\": \"\u003Cfrom sign-up>\", \"last_name\": \"\u003Cfrom sign-up>\", \"email\": \"\u003Cfrom sign-up>\", \"date_of_birth\": \"1994-05-12T00:00:00Z\", \"tax_id\": \"12345678\", \"phone_number\": \"+13022006100\", \"address_line_1\": \"8 The Green\", \"address_line_2\": \"#12345\", \"city\": \"Dover\", \"state_province_region\": \"DE\", \"country\": \"US\", \"postal_code\": \"02050\", \"ip_address\": \"127.0.0.1\", \"id_doc_country\": \"US\", \"id_doc_type\": \"PASSPORT\", \"id_doc_front_file\": \"https:\u002F\u002Fplacehold.co\u002F800x1000.jpg\", \"selfie_file\": \"https:\u002F\u002Fplacehold.co\u002F800x1000.jpg\", \"proof_of_address_doc_type\": \"UTILITY_BILL\", \"proof_of_address_doc_file\": \"https:\u002F\u002Fplacehold.co\u002F800x1000.jpg\"}. BlindPay downloads every document URL: data: URIs are rejected and dead links fail with FILES_UNREADABLE. The response is only {\"id\", \"customer_id\"}; GET \u002Finstances\u002F{instance_id}\u002Fcustomers\u002F{id} shows kyc_status, which reached approved within 5 seconds in testing. A first name of \"Fail\" forces a rejection.\n- Wallet: POST \u002Finstances\u002F{instance_id}\u002Fcustomers\u002F{customer_id}\u002Fwallets with {\"network\": \"base_sepolia\", \"name\": \"Main account\", \"external_id\": \"\u003Cyour user id>\"} returns id (bl_...) and address. Store both. GET \u002Finstances\u002F{instance_id}\u002Fcustomers\u002F{customer_id}\u002Fwallets\u002F{wallet_id}\u002Fbalance returns one entry per token, like {\"USDB\": {\"amount\": 106.64}, \"USDC\": {...}}. amount is in whole tokens, so cents = Math.round(amount * 100). This endpoint is the balance; never compute it from transactions.\n- US account: POST \u002Finstances\u002F{instance_id}\u002Fcustomers\u002F{customer_id}\u002Fvirtual-accounts with {\"banking_partner\": \"jpmorgan\", \"token\": \"USDB\", \"blockchain_wallet_id\": \"\u003Cthe bl_ wallet id>\"}. The field is named blockchain_wallet_id but takes the managed wallet id. On development it comes back approved at once; us.ach and us.wire hold routing_number (always 110000000 on development) and account_number. Bank names and addresses come back as the literal \"\u003Cdevelopment>\" there, so hide any field with that value.\n- Mexican CLABE: the same call with \"banking_partner\": \"spei\" returns mx.spei.clabe and mx.beneficiary.name. A customer gets one account per banking partner, so create each once, store it, and never recreate it on a page load.\n- Simulated SPEI deposit (development only): POST \u002Finstances\u002F{instance_id}\u002Fcustomers\u002F{customer_id}\u002Fvirtual-accounts\u002F{virtual_account_id}\u002Fsimulate-spei-deposit with {\"amount\": \u003CMXN cents>, \"sender_name\": \"Juan Perez\"} returns {\"success\": true}. Within about 10 seconds a completed payin with payment_method \"spei\" shows up in GET \u002Finstances\u002F{instance_id}\u002Fpayins?customer_id=\u003Cid>&limit=10 and the balance rises. The sender's name is in the payin's tracking_transaction.sender_name. MXN 2,000.00 delivered 106.64 USDB in testing.\n- Payin by Pix: POST \u002Finstances\u002F{instance_id}\u002Fpayin-quotes with {\"wallet_id\": \"\u003Cbl_>\", \"currency_type\": \"sender\", \"cover_fees\": true, \"request_amount\": \u003CBRL cents, at least 1000>, \"payment_method\": \"pix\", \"token\": \"USDB\"}. No network field: the wallet decides it. With cover_fees true the fee is added to what the payer sends, so show the quote's sender_amount as the amount to pay and sender_amount minus request_amount as the fee (R$500.00 became R$501.00 in testing, while flat_fee said R$0.10). Within 5 minutes, POST \u002Finstances\u002F{instance_id}\u002Fpayins\u002Fevm with {\"payin_quote_id\": \"\u003Cid>\"} (this endpoint serves every rail). The payin has pix_code, which is the literal string \"\u003Cdevelopment>\" on development, so show a sandbox note instead of a QR code. It completes by itself about 30 seconds later.\n- Recipients: POST \u002Finstances\u002F{instance_id}\u002Fcustomers\u002F{customer_id}\u002Fbank-accounts. The rails are pix, spei_bitso (Mexico: the payin payment_method is spei, but the bank account type is spei_bitso), and ach. GET \u002Favailable\u002Fbank-details?rail=\u003Crail> returns each field's key, label, required, regex, and choices under items (each with label, value, and sometimes is_active); build the forms from it. Pix needs only {\"type\": \"pix\", \"name\", \"pix_key\"}; bank-details lists only pix_key, so name is your own field. SPEI needs spei_protocol \"clabe\", spei_clabe (18 digits with a check digit; 012180001234567899 is valid for tests), and beneficiary_name. ACH needs beneficiary_name, routing_number (021000021 works for tests), account_number, account_type (checking or saving), account_class (individual), recipient_relationship (for example family), address_line_1, city, state_province_region, country, and postal_code.\n- Payout: POST \u002Finstances\u002F{instance_id}\u002Fquotes with {\"bank_account_id\": \"\u003Cba_>\", \"currency_type\": \"sender\", \"cover_fees\": false, \"request_amount\": \u003CUSD cents, at least 500>, \"network\": \"base_sepolia\", \"token\": \"USDB\"} returns sender_amount, receiver_amount (cents of the recipient's currency), flat_fee, and expires_at (epoch milliseconds, 5 minutes out). Ignore the contract field: it is for wallets the customer signs for. The quotation fields are scaled by 100 (an ACH quote returns 100 for a 1.00 rate), so show the rate as receiver_amount \u002F sender_amount instead. Then POST \u002Finstances\u002F{instance_id}\u002Fpayouts\u002Fevm with {\"quote_id\": \"\u003Cqu_>\", \"sender_wallet_address\": \"\u003Cmanaged wallet address>\"}: a managed wallet needs no signature or approval step. It goes from processing to completed within seconds on development. A request_amount of 77700 ends refunded about 15 seconds later, with the USDB back in the wallet (it also appears as a wallet deposit). A request_amount of 66600 ends failed, and the USDB that left the wallet stays out on development.\n- Friend transfer: POST \u002Finstances\u002F{instance_id}\u002Ftransfer-quotes with {\"wallet_id\": \"\u003Csender bl_>\", \"amount_reference\": \"sender\", \"request_amount\": \u003CUSD cents>, \"sender_token\": \"USDB\", \"customer_wallet_address\": \"\u003Crecipient wallet address>\", \"customer_token\": \"USDB\", \"customer_network\": \"base_sepolia\", \"cover_fees\": true}, then right away POST \u002Finstances\u002F{instance_id}\u002Ftransfers with {\"transfer_quote_id\": \"\u003Cid>\"}. The quote id starts with qu_ (some docs say pq_). It completed in about 5 seconds in testing. Test transfers with ordinary amounts: 66600 and 77700 are for payins and payouts.\n- Lists: GET \u002Finstances\u002F{instance_id}\u002Fpayins, \u002Fpayouts, and \u002Ftransfers filter by customer_id and return {\"data\": [...], \"pagination\": {...}} when you pass limit, which must be 10, 50, 100, 200, 500, or 1000 (anything else is a 400). A customer's wallets, virtual accounts, and bank accounts come back as plain arrays.\n- Activity feed: GET ...\u002Fwallets\u002F{wallet_id}\u002Fdeposits lists every inbound movement, payin settlements included, so adding it to payins double counts. A friend transfer shows up for the receiver only there. Record both sides of every friend transfer in your own store when you create it, refresh its status with GET \u002Finstances\u002F{instance_id}\u002Ftransfers\u002F{id}, and build the feed from payins, payouts, and those records.\n- Idempotency: send an Idempotency-Key header with a fresh UUID per user action on every POST that creates a customer, quote, payin, payout, or transfer. Reuse it only to retry that same action.\n- ID prefixes: customer re_, wallet bl_, virtual account va_, bank account ba_, quote qu_, payin pi_, payout po_, transfer tr_, terms to_.\n\n## Verify before you report\n\n1. npm run build passes with no type errors, and lint passes if the scaffold set it up.\n2. Vitest unit tests cover the money helpers and the BlindPay client (error mapping, 429 retry), with fetch mocked.\n3. Run the production build (npm start on the chosen port) in the background, logging to .data\u002Fserver.log.\n4. Install @playwright\u002Ftest with Chromium and write tests\u002Fe2e\u002Fdemo.spec.ts. It drives the real UI against the development instance, one step at a time, and saves a full-page screenshot of every screen to screenshots\u002F:\n   a. Sign up Maria Santos with a unique email (maria+\u003Ctimestamp>@example.com), wait for the BlindPay terms page (https:\u002F\u002Fapp.blindpay.com\u002Fe\u002Fterms-of-service), click the button named exactly \"Accept\" (the page also has a hidden \"Accepted\" button), wait until the URL is back on your own host at \u002Fonboarding\u002Fterms (BlindPay's own URL contains your redirect_url, so a path match alone fires too early), submit identity, and wait for the account to be ready.\n   b. Simulate a SPEI transfer of MXN 20,000.00 and wait for the balance to rise. That funds the failure tests in step f.\n   c. Deposit R$ 500.00 by Pix and wait for completed.\n   d. Add a Brazil Pix recipient and send $50.00; wait for completed. Add a Mexico SPEI recipient and send $25.00; wait for completed.\n   e. Sign up Lucas Almeida the same way. As Maria, send Lucas $20.00 and check both balances.\n   f. As Maria, send $777.00 to the Pix recipient and check that it shows as refunded and the balance comes back. Then send $666.00 and check that it shows as failed.\n   Settlement waits get up to 2 minutes each. Let the app's polling do the work and keep the pace under the rate limit. If you run the spec in the background, wait for it to finish: a status line while you wait is fine, a question is not.\n5. Fix what fails and rerun until the whole spec passes. If one step still fails after three real attempts, leave the rest working and report that step as broken, with the error.\n6. Leave the app running on its port and open it in the default browser (open on macOS, xdg-open on Linux, start on Windows).\n\n## Final report\n\nThis is your only message. Plain text, short, in this order:\n1. The URL, and the email to sign in with (Maria from the test run, already funded and with history).\n2. A 60-second demo script: what to click and what appears.\n3. What was verified, with the BlindPay IDs created and the final balances.\n4. Where the screenshots are.\n5. How to start it again.\n6. What changes for production: a production instance and key, USDC or USDT on a mainnet network, real document upload (POST \u002Fv1\u002Fupload), real authentication, webhooks with signature verification instead of polling, and removing the sandbox buttons.\n7. Every place the live API disagreed with this prompt.\n```\n\n## How to use\n\n1. Sign up at [app.blindpay.com](https:\u002F\u002Fapp.blindpay.com), create a development instance, and create an API key in its **API Keys** tab.\n2. In an empty folder, create a `.env` file with `BLINDPAY_API_KEY=...` and `BLINDPAY_INSTANCE_ID=in_...`.\n3. Start your agent with permission prompts off, or it will stop to ask before every command. In Claude Code: `claude --dangerously-skip-permissions`.\n4. Paste the prompt. To pick the name, add one line after it, like \"Call it Pampa\".\n5. Come back in about 30 minutes. The app opens in your browser with a funded test account and a demo script.\n\nNo `.env`? The agent still builds everything and asks for the two values once, at the end.\n\n## Related docs\n\n- [Sandbox vs. production](https:\u002F\u002Fblindpay.com\u002Fdocs\u002Flearn\u002Fsandbox-vs-production)\n- [Managed wallets](https:\u002F\u002Fblindpay.com\u002Fdocs\u002Fwallets)\n- [Virtual accounts](https:\u002F\u002Fblindpay.com\u002Fdocs\u002Fvirtual-accounts)\n- [Payin quotes](https:\u002F\u002Fblindpay.com\u002Fdocs\u002Fpayin-quotes)\n- [Payout quotes](https:\u002F\u002Fblindpay.com\u002Fdocs\u002Fpayout-quotes)\n- [Transfers](https:\u002F\u002Fblindpay.com\u002Fdocs\u002Ftransfers)\n",{"title":5,"description":144},"Build a neobank on BlindPay with one AI agent prompt","prompts\u002Fbuild-a-neobank","OQPCpmMDoprvDhyaOOZ53VAMDUK476QQg0jNokI7WgQ",[162,166,170,171,175,179,183,187,191,195,199,203,207,211,215,219,223,227,231,235,239,243],{"path":163,"title":164,"description":165},"\u002Fprompts\u002Fbuild-a-global-checkout","Build a global checkout","One prompt, no questions: your coding agent builds and tests a hosted checkout platform on a BlindPay development instance. Merchants onboard with KYB, create checkout sessions through an API, and get paid in dollars while shoppers pay by Pix, SPEI, ACH, wire, RTP, Argentine bank transfer, or PSE.",{"path":167,"title":168,"description":169},"\u002Fprompts\u002Fbuild-contractor-payouts","Build a global contractor payout product","Compose onboarding, bank accounts, quotes, payouts, and reconciliation into a complete pay-your-contractors feature across Pix, SPEI, SEPA, and ACH.",{"path":149,"title":5,"description":144},{"path":172,"title":173,"description":174},"\u002Fprompts\u002Fconnect-ai-agent-mcp","Connect an AI agent with the MCP server","Wire Claude, Cursor, or any MCP-compatible host to the BlindPay API with the official MCP server and agent skills, with guardrails for money movement.",{"path":176,"title":177,"description":178},"\u002Fprompts\u002Fintegrate-external-wallet-payouts","Fund payouts from external wallets","Let customers pay out from their own EVM, Solana, or Stellar wallets: signed-message registration plus the on-chain authorization step per chain.",{"path":180,"title":181,"description":182},"\u002Fprompts\u002Fintegrate-circle-wallets","Integrate Circle wallets with BlindPay","Fund BlindPay payouts from Circle developer-controlled wallets: sign the registration challenge and the ERC-20 approve through Circle's API instead of a browser wallet.",{"path":184,"title":185,"description":186},"\u002Fprompts\u002Fintegrate-dfns","Integrate Dfns with BlindPay","Fund BlindPay stablecoin payouts from Dfns MPC wallets: sign the registration challenge and the ERC-20 approve through Dfns's User Action Signature flow.",{"path":188,"title":189,"description":190},"\u002Fprompts\u002Fintegrate-fireblocks","Integrate Fireblocks with BlindPay","Fund BlindPay stablecoin payouts from Fireblocks vault accounts: MPC-signed wallet registration and the ERC-20 approve through Fireblocks' transactions API.",{"path":192,"title":193,"description":194},"\u002Fprompts\u002Fintegrate-privy","Integrate Privy with BlindPay","Fund BlindPay stablecoin payouts from Privy Server Wallets: sign the registration challenge and the ERC-20 approve through Privy's wallet RPC endpoint.",{"path":196,"title":197,"description":198},"\u002Fprompts\u002Fintegrate-virtual-accounts","Integrate US virtual accounts","Give each customer a named US bank account with ACH, RTP, wire, and SWIFT details that settles automatically to USDC or USDT in their wallet.",{"path":200,"title":201,"description":202},"\u002Fprompts\u002Fintegrate-utila","Integrate Utila with BlindPay","Fund BlindPay payouts from Utila MPC vaults: sign the wallet-registration challenge and the ERC-20 approve through Utila's service-account API, with async transaction confirmation handled.",{"path":204,"title":205,"description":206},"\u002Fprompts\u002Fintegrate-global-checkout","Integrate a global checkout","Add a hosted checkout to your existing app: checkout sessions, a payment page for Pix, SPEI, ACH, wire, RTP, Argentine bank transfer, and PSE, USD settlement in stablecoins, and webhooks. Works for one merchant or a platform of many.",{"path":208,"title":209,"description":210},"\u002Fprompts\u002Fintegrate-customer-onboarding","Integrate customer onboarding with KYC and KYB","Build the full onboarding pipeline: terms of service, individual and business customers, document uploads, RFI handling, and status webhooks.",{"path":212,"title":213,"description":214},"\u002Fprompts\u002Fintegrate-offramp-wallets","Integrate offramp wallets for auto-conversion","Give each bank account a dedicated crypto deposit address: stablecoins sent to it convert and pay out to the linked bank account automatically.",{"path":216,"title":217,"description":218},"\u002Fprompts\u002Fintegrate-payins","Integrate payins from bank transfers to stablecoins","Accept Pix, ACH, wire, SPEI, and other local bank transfers and settle them as USDC or USDT in a wallet, with quotes, payment instructions, and webhooks.",{"path":220,"title":221,"description":222},"\u002Fprompts\u002Fintegrate-quotes-fx","Integrate quotes and FX handling","Handle payin, payout, and transfer quotes correctly: expiry windows, currency_type conventions, fees, and displaying rates to users.",{"path":224,"title":225,"description":226},"\u002Fprompts\u002Fintegrate-stablecoin-payouts","Integrate stablecoin payouts end to end","Build a complete stablecoin to fiat payout flow: customer onboarding, bank accounts, quotes, and payout execution over Pix, ACH, SPEI, SEPA, and more.",{"path":228,"title":229,"description":230},"\u002Fprompts\u002Fintegrate-blindpay-wallet","Integrate the BlindPay wallet","Hold customer stablecoin balances in BlindPay-custodied wallets: create the wallet, collect payins into it, pay out from it with no signing step.",{"path":232,"title":233,"description":234},"\u002Fprompts\u002Fintegrate-wallet-transfers","Integrate wallet transfers and cross-chain USDC","Move stablecoins from managed wallets to any address with transfer quotes, including cross-chain USDC over Circle CCTP v2.",{"path":236,"title":237,"description":238},"\u002Fprompts\u002Fintegrate-webhooks","Integrate webhooks end to end","Register endpoints, verify Svix signatures correctly, deduplicate retries, and drive payment state from the full BlindPay event catalog.",{"path":240,"title":241,"description":242},"\u002Fprompts\u002Fintegrate-invoice-payables","Pay US vendor invoices with payables","Register supplier invoices with line items and the vendor's ACH or wire details, prefill them from the PDF with AI, and settle them from stablecoins through the quote-and-execute flow.",{"path":244,"title":245,"description":246},"\u002Fprompts\u002Fintegrate-payables","Pay boletos and Brazilian bills with payables","Register boletos, arrecadacao slips, and PIX codes as payables and settle them from stablecoins through the quote-and-execute flow.",1793903173632]