216 lines
7.0 KiB
Markdown
216 lines
7.0 KiB
Markdown
# Wise Payment Integration - Complete Setup
|
|
|
|
This document describes the Wise payment integration that has been added to the oracle project, mirroring the implementation from the KSA-ORACLE project.
|
|
|
|
## Overview
|
|
|
|
The Wise payment integration allows you to programmatically create international money transfers using the Wise API. This is a full API integration that enables:
|
|
|
|
- Creating recipient accounts
|
|
- Generating transfer quotes
|
|
- Initiating transfers
|
|
- Funding transfers from your Wise balance
|
|
- Tracking transfer status via webhooks
|
|
|
|
## Backend Components
|
|
|
|
### 1. WisePaymentController (`app/Http/Controllers/WisePaymentController.php`)
|
|
|
|
Main controller that handles:
|
|
- **`createTransfer()`** - Creates a complete transfer flow (recipient → quote → transfer → funding)
|
|
- **`handleWebhook()`** - Processes Wise webhook notifications for transfer status updates
|
|
- **`checkTransferStatus()`** - Manually checks the status of a transfer
|
|
|
|
### 2. Payment Model (`app/Models/Payment.php`)
|
|
|
|
Updated with the following Wise-specific fields:
|
|
- `wise_transfer_id` - The Wise transfer ID
|
|
- `wise_recipient_id` - The recipient account ID in Wise
|
|
- `wise_quote_id` - The quote ID for the transfer
|
|
- `target_currency` - The currency the recipient will receive
|
|
- `recipient_name` - Name of the transfer recipient
|
|
- `recipient_email` - Email of the recipient
|
|
- `error_message` - Stores any error messages from failed transfers
|
|
- `payment_provider` - Set to 'wise' or 'stripe'
|
|
- `wise_payment_id` - Generic Wise payment identifier
|
|
- `wise_session_id` - Session tracking for Wise payments
|
|
|
|
### 3. Database Migrations
|
|
|
|
Two migrations have been created and applied:
|
|
|
|
**Migration 1:** `2025_10_14_130637_add_wise_fields_to_payments_table.php`
|
|
- Adds: `payment_provider`, `wise_payment_id`, `wise_session_id`
|
|
|
|
**Migration 2:** `2025_10_14_145926_add_wise_transfer_fields_to_payments_table.php`
|
|
- Adds: `wise_transfer_id`, `wise_recipient_id`, `wise_quote_id`, `target_currency`, `recipient_name`, `recipient_email`, `error_message`
|
|
|
|
### 4. API Routes (`routes/api.php`)
|
|
|
|
```php
|
|
Route::post('/api/wise/transfer', [WisePaymentController::class, 'createTransfer']);
|
|
Route::post('/api/wise/webhook', [WisePaymentController::class, 'handleWebhook']);
|
|
```
|
|
|
|
## Frontend Components
|
|
|
|
### 1. TypeScript Actions (`resources/js/actions/App/Http/Controllers/WisePaymentController.ts`)
|
|
|
|
Auto-generated route helpers for type-safe API calls:
|
|
- `createTransfer.post()` - Call the transfer creation endpoint
|
|
- `handleWebhook.post()` - Webhook endpoint (for backend use)
|
|
|
|
### 2. Checkout Page (`resources/js/pages/Checkout.vue`)
|
|
|
|
A complete Vue component with a form that includes:
|
|
- Amount input
|
|
- Source and target currency selection
|
|
- Recipient information (name, email, account number)
|
|
- Payment reason
|
|
- Error and success message handling
|
|
- Loading state management
|
|
|
|
## Configuration
|
|
|
|
### Environment Variables
|
|
|
|
Add these to your `.env` file (already documented in `.env.example`):
|
|
|
|
```bash
|
|
# Wise API Integration
|
|
WISE_API_KEY=your_wise_api_token_here
|
|
WISE_PROFILE_ID=your_wise_profile_id_here
|
|
|
|
# Wise Webhook Secret (optional, for webhook signature verification)
|
|
WISE_WEBHOOK_SECRET=your_webhook_secret_here
|
|
```
|
|
|
|
### Getting Your Wise Credentials
|
|
|
|
1. **API Key**:
|
|
- Go to https://wise.com/settings/api-tokens
|
|
- Create a new token with appropriate permissions
|
|
- Use either sandbox (test) or live API key
|
|
|
|
2. **Profile ID**:
|
|
- Go to https://wise.com/settings/
|
|
- Find your business or personal profile ID
|
|
- This is usually a numeric ID
|
|
|
|
3. **Webhook Secret** (optional):
|
|
- Go to https://wise.com/settings/webhooks
|
|
- Create a webhook pointing to: `https://yourdomain.com/api/wise/webhook`
|
|
- Copy the webhook secret for signature verification
|
|
|
|
## Usage Example
|
|
|
|
### Creating a Transfer from Frontend
|
|
|
|
```javascript
|
|
import WisePaymentController from '@/actions/App/Http/Controllers/WisePaymentController'
|
|
import axios from 'axios'
|
|
|
|
const formData = {
|
|
amount: 100.00,
|
|
source_currency: 'USD',
|
|
target_currency: 'EUR',
|
|
recipient_name: 'John Doe',
|
|
recipient_email: 'john@example.com',
|
|
recipient_account_number: '1234567890',
|
|
reason: 'Payment for services'
|
|
}
|
|
|
|
const response = await axios.post('/api/wise/transfer', formData)
|
|
|
|
if (response.data.success) {
|
|
console.log('Transfer ID:', response.data.transfer_id)
|
|
console.log('Payment ID:', response.data.payment_id)
|
|
}
|
|
```
|
|
|
|
### Backend Transfer Creation Flow
|
|
|
|
1. **Validates** the request data
|
|
2. **Creates** a Payment record with status 'pending'
|
|
3. **Creates** a recipient account in Wise
|
|
4. **Generates** a quote for the transfer
|
|
5. **Creates** the transfer in Wise
|
|
6. **Funds** the transfer from your Wise balance
|
|
7. **Updates** the Payment record with transfer details and status 'processing'
|
|
8. **Returns** the transfer ID and payment ID
|
|
|
|
## Webhook Handling
|
|
|
|
When Wise sends a webhook notification:
|
|
|
|
1. The `handleWebhook()` method receives the payload
|
|
2. Extracts the transfer ID from the webhook data
|
|
3. Finds the corresponding Payment record
|
|
4. Updates the payment status based on the transfer state
|
|
5. Logs the webhook for debugging
|
|
|
|
## Database Schema
|
|
|
|
The `payments` table now includes these fields for Wise integration:
|
|
|
|
```sql
|
|
payment_provider VARCHAR(255) DEFAULT 'stripe'
|
|
wise_payment_id VARCHAR(255) NULLABLE
|
|
wise_session_id VARCHAR(255) NULLABLE
|
|
wise_transfer_id VARCHAR(255) NULLABLE
|
|
wise_recipient_id VARCHAR(255) NULLABLE
|
|
wise_quote_id VARCHAR(255) NULLABLE
|
|
target_currency VARCHAR(10) NULLABLE
|
|
recipient_name VARCHAR(255) NULLABLE
|
|
recipient_email VARCHAR(255) NULLABLE
|
|
error_message TEXT NULLABLE
|
|
```
|
|
|
|
## Payment Status Flow
|
|
|
|
1. **pending** - Payment record created
|
|
2. **processing** - Transfer created and funded in Wise
|
|
3. **succeeded** / **failed** - Final status from Wise webhook
|
|
|
|
## Dependencies
|
|
|
|
- **GuzzleHTTP** (`guzzlehttp/guzzle: ^7.10`) - Already installed
|
|
- Used for making HTTP requests to the Wise API
|
|
|
|
## Testing
|
|
|
|
To test the integration:
|
|
|
|
1. Use Wise's sandbox environment first
|
|
2. Set `WISE_API_KEY` to your sandbox API key
|
|
3. Create test transfers to verify the flow
|
|
4. Monitor the Laravel logs for any API errors
|
|
5. Test webhook delivery using Wise's webhook testing tools
|
|
|
|
## Security Considerations
|
|
|
|
1. **Never commit** your `.env` file with real API keys
|
|
2. Store `WISE_API_KEY` securely (use Laravel secrets in production)
|
|
3. Implement webhook signature verification using `WISE_WEBHOOK_SECRET`
|
|
4. Validate all user inputs before creating transfers
|
|
5. Use HTTPS in production for webhook endpoints
|
|
|
|
## Additional Resources
|
|
|
|
- [Wise API Documentation](https://api-docs.wise.com/)
|
|
- [Wise Sandbox Environment](https://sandbox.transferwise.tech/)
|
|
- [Webhook Setup Guide](https://api-docs.wise.com/#webhooks)
|
|
|
|
## Notes
|
|
|
|
- The Wise API requires your account to have sufficient balance to fund transfers
|
|
- Some recipient types require additional fields (bank codes, IBAN, etc.)
|
|
- Transfer times vary by currency corridor
|
|
- API rate limits apply based on your Wise account tier
|
|
|
|
---
|
|
|
|
**Integration Status**: ✅ Complete
|
|
**Last Updated**: October 14, 2025
|
|
**Project**: oracle (/media/creator/6226b912-8ba7-45dc-88a2-4b10d3dd1655/kandra/oracle)
|