6.8 KiB
Wise Payment Integration Setup Guide
This guide explains how to set up and use the Wise payment integration for your tarot card reading application.
Overview
The Wise integration allows users to pay for card readings using Wise (formerly TransferWise) alongside the existing Stripe integration. When a user selects a paid option, they can now choose between Stripe and Wise as their payment provider.
Flow
- Card Selection - User selects a paid reading option (6 or 18 cards)
- Payment Provider Choice - User clicks either "Stripe" or "Wise" button
- Payment Creation - Backend creates a payment session with Wise API
- Payment Redirect - User is redirected to Wise payment page
- Webhook Verification - Wise sends webhook to confirm payment
- Access to Tirage - Once payment is verified (status = 'succeeded'), user can draw cards
Database Changes
Migration
Run the migration to add Wise fields to the payments table:
php artisan migrate
This adds:
payment_provider- Identifies whether payment is 'stripe' or 'wise'wise_payment_id- Wise transfer IDwise_session_id- Wise session identifier
Configuration
1. Set Up Wise Account
- Create a Wise Business account at https://wise.com
- Navigate to Settings → API tokens
- Create a new API token with appropriate permissions
- Get your Profile ID from the API settings
2. Environment Variables
Add these to your .env file:
# Wise Payment Configuration
WISE_API_URL=https://api.wise.com # Use https://sandbox.transferwise.tech for testing
WISE_API_TOKEN=your_wise_api_token_here
WISE_PROFILE_ID=your_profile_id_here
WISE_WEBHOOK_SECRET=your_webhook_secret_here
WISE_RECIPIENT_NAME="Your Business Name"
WISE_RECIPIENT_EMAIL=payments@yourbusiness.com
For Testing:
- Use
WISE_API_URL=https://sandbox.transferwise.techfor sandbox environment - Create a sandbox account at https://sandbox.transferwise.tech
3. Configure Webhooks
In your Wise account:
- Go to Settings → Webhooks
- Create a new webhook
- Set the URL to:
https://yourdomain.com/wise/webhook - Subscribe to these events:
transfers#state-change- For transfer status updatesbalance_credit- For balance credit notifications
- Copy the webhook secret and add it to your
.envasWISE_WEBHOOK_SECRET
API Endpoints
Payment Creation
POST /create-wise-payment
Request:
{
"count": 6 // or 18
}
Response:
{
"success": true,
"paymentUrl": "https://api.wise.com/pay/12345",
"transferId": "12345",
"clientSessionId": "uuid-here"
}
Webhook Handler
POST /wise/webhook
Receives Wise webhook events and updates payment status.
Payment Validation
GET /wise/validate-payment?client_session_id={uuid}
Response:
{
"success": true,
"drawCount": 6
}
Frontend Changes
The cardSelection.vue component now has dual payment buttons:
- Stripe Button (Gold) - Uses existing Stripe flow
- Wise Button (Dark Blue) - Uses new Wise flow
Both buttons appear for the paid options (6 cards and 18 cards).
How It Works
Payment Flow
- User clicks "Wise" button on card selection
redirectToWisePayment()function calls/create-wise-payment- Backend:
- Creates Wise quote for the amount
- Creates recipient account
- Creates transfer with customer transaction ID
- Stores payment record with
status='pending'andpayment_provider='wise'
- User is redirected to Wise payment page
- User completes payment on Wise
- Wise sends webhook to
/wise/webhook - Webhook handler updates payment status to
'succeeded' - User returns to success page
- Success page validates payment status
- If payment succeeded, user can proceed to draw cards
Webhook Handling
The WiseController::handleWebhook() method processes:
-
transfer_state_change: Updates payment status based on transfer state
outgoing_payment_sent→processingfunds_refunded→refundedbounced_back→failed
-
balance_credit: Marks payment as
succeededwhen funds are received
Payment Verification
Before allowing card drawing, the system checks:
- Payment exists in database
client_session_idmatchesstatusis'succeeded'payment_provideris'wise'
This happens in the /success route and ensures users can only draw cards after payment is confirmed.
Important Notes
Wise API Differences from Stripe
Unlike Stripe Checkout, Wise doesn't have a hosted payment page URL that you redirect to directly. The implementation provided creates the transfer but you'll need to implement one of these options:
Option 1: Manual Payment Instructions
- Show users the transfer details and ask them to pay manually
- Check status via webhooks or polling
Option 2: Wise Payment Links (Recommended)
- Use Wise's payment link feature (if available in your region)
- Contact Wise support to enable this feature
Option 3: Custom Integration
- Build a custom payment form that collects payment method details
- Use Wise API to process the payment
Testing
For testing, you can:
- Use Wise sandbox environment
- Manually update payment status in database:
UPDATE payments SET status='succeeded' WHERE client_session_id='your-uuid'; - Test webhook with Wise's webhook testing tool
Security
- Webhook signatures are verified using HMAC-SHA256
- Payment validation checks status before allowing card draws
- One-time use - Cards can only be drawn once per payment
Troubleshooting
Webhook not receiving events
- Check your webhook URL is publicly accessible
- Verify
WISE_WEBHOOK_SECRETmatches Wise dashboard - Check Laravel logs:
storage/logs/laravel.log
Payment not marking as succeeded
- Check webhook is being received (check logs)
- Verify payment record exists with correct
wise_payment_id - Manually check transfer status via Wise dashboard
User can't draw cards after payment
- Verify payment status is
'succeeded'in database - Check
client_session_idis being passed correctly in URL - Verify payment provider is set to
'wise'
Next Steps
- Run the migration:
php artisan migrate - Configure .env: Add all Wise environment variables
- Set up webhooks: Configure in Wise dashboard
- Test in sandbox: Use Wise sandbox for testing
- Go live: Switch to production API URL and credentials
Support
For Wise API documentation, visit:
- API Docs: https://docs.wise.com/api-docs/
- Sandbox: https://sandbox.transferwise.tech
- Support: https://wise.com/help/
For issues with this integration, check the Laravel logs and Wise dashboard for detailed error messages.