PHP Examples
Complete examples for integrating EasySlip API with PHP.
Requirements
- PHP 7.4+
- cURL extension
API Client Class
php
<?php
// EasySlipClient.php
class EasySlipClient
{
private string $apiKey;
private string $baseUrl;
public function __construct(string $apiKey, string $version = 'v2')
{
$this->apiKey = $apiKey;
$this->baseUrl = "https://developer.easyslip.com/api/{$version}";
}
private function request(
string $endpoint,
string $method = 'GET',
array $data = [],
bool $isMultipart = false
): array {
$ch = curl_init();
$headers = [
'Authorization: Bearer ' . $this->apiKey,
];
$options = [
CURLOPT_URL => $this->baseUrl . $endpoint,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
];
if ($method === 'POST') {
$options[CURLOPT_POST] = true;
if ($isMultipart) {
$options[CURLOPT_POSTFIELDS] = $data;
} else {
$headers[] = 'Content-Type: application/json';
$options[CURLOPT_POSTFIELDS] = json_encode($data);
}
}
$options[CURLOPT_HTTPHEADER] = $headers;
curl_setopt_array($ch, $options);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
if ($error) {
throw new Exception("cURL Error: {$error}");
}
return json_decode($response, true);
}
/**
* Verify slip by payload (V2)
*/
public function verifyByPayload(string $payload, array $options = []): array
{
$data = array_merge(['payload' => $payload], $options);
return $this->request('/verify/bank', 'POST', $data);
}
/**
* Verify slip by URL (V2)
*/
public function verifyByUrl(string $url, array $options = []): array
{
$data = array_merge(['url' => $url], $options);
return $this->request('/verify/bank', 'POST', $data);
}
/**
* Verify slip by Base64 (V2)
*/
public function verifyByBase64(string $base64, array $options = []): array
{
$data = array_merge(['base64' => $base64], $options);
return $this->request('/verify/bank', 'POST', $data);
}
/**
* Verify slip by image file (V2)
*/
public function verifyByImage(string $filePath, array $options = []): array
{
$data = [
'image' => new CURLFile($filePath),
];
foreach ($options as $key => $value) {
$data[$key] = is_bool($value) ? ($value ? 'true' : 'false') : $value;
}
return $this->request('/verify/bank', 'POST', $data, true);
}
/**
* Get application info (V2)
*/
public function getInfo(): array
{
return $this->request('/info');
}
}Usage Examples
Basic Verification
php
<?php
require_once 'EasySlipClient.php';
$client = new EasySlipClient(getenv('EASYSLIP_API_KEY'));
// Verify by payload
$result = $client->verifyByPayload('YOUR_QR_PAYLOAD', [
'checkDuplicate' => true,
]);
if ($result['success']) {
$slip = $result['data']['rawSlip'];
echo "Transaction: " . $slip['transRef'] . "\n";
echo "Amount: " . $slip['amount']['amount'] . " THB\n";
echo "Sender: " . $slip['sender']['account']['name']['th'] . "\n";
echo "Receiver: " . $slip['receiver']['account']['name']['th'] . "\n";
if ($result['data']['isDuplicate']) {
echo "Warning: This slip was verified before!\n";
}
} else {
echo "Error: " . $result['error']['message'] . "\n";
}Laravel Integration
php
<?php
// app/Services/EasySlipService.php
namespace App\Services;
use Illuminate\Support\Facades\Http;
class EasySlipService
{
private string $apiKey;
private string $baseUrl = 'https://api.easyslip.com/v2';
public function __construct()
{
$this->apiKey = config('services.easyslip.key');
}
public function verifyByPayload(string $payload, array $options = []): array
{
$response = Http::withToken($this->apiKey)
->post("{$this->baseUrl}/verify/bank", [
'payload' => $payload,
...$options,
]);
return $response->json();
}
public function verifyByUrl(string $url, array $options = []): array
{
$response = Http::withToken($this->apiKey)
->post("{$this->baseUrl}/verify/bank", [
'url' => $url,
...$options,
]);
return $response->json();
}
public function verifyByImage($file, array $options = []): array
{
$response = Http::withToken($this->apiKey)
->attach('image', $file->get(), $file->getClientOriginalName())
->post("{$this->baseUrl}/verify/bank", $options);
return $response->json();
}
public function getInfo(): array
{
$response = Http::withToken($this->apiKey)
->get("{$this->baseUrl}/info");
return $response->json();
}
}Laravel Controller
php
<?php
// app/Http/Controllers/SlipVerificationController.php
namespace App\Http\Controllers;
use App\Services\EasySlipService;
use Illuminate\Http\Request;
class SlipVerificationController extends Controller
{
public function __construct(
private EasySlipService $easySlip
) {}
public function verify(Request $request)
{
$request->validate([
'slip' => 'required|image|max:4096',
'order_id' => 'required|string',
'expected_amount' => 'required|numeric',
]);
$result = $this->easySlip->verifyByImage($request->file('slip'), [
'remark' => $request->order_id,
'matchAmount' => $request->expected_amount,
'checkDuplicate' => true,
]);
if (!$result['success']) {
return response()->json([
'error' => $result['error']['message'],
], 400);
}
$data = $result['data'];
if ($data['isDuplicate']) {
return response()->json([
'error' => 'This slip has already been used',
], 400);
}
if (isset($data['isAmountMatched']) && !$data['isAmountMatched']) {
return response()->json([
'error' => 'Amount does not match',
'expected' => $request->expected_amount,
'actual' => $data['rawSlip']['amount']['amount'],
], 400);
}
// Process payment
// Order::find($request->order_id)->update(['status' => 'paid']);
return response()->json([
'success' => true,
'transRef' => $data['rawSlip']['transRef'],
'amount' => $data['rawSlip']['amount']['amount'],
]);
}
}WordPress/WooCommerce Integration
php
<?php
// wp-content/plugins/easyslip-verify/easyslip-verify.php
/**
* Plugin Name: EasySlip Verification
* Description: Verify bank slips for WooCommerce orders
*/
class EasySlipVerify
{
private $api_key;
public function __construct()
{
$this->api_key = get_option('easyslip_api_key');
add_action('wp_ajax_verify_slip', [$this, 'verify_slip']);
add_action('wp_ajax_nopriv_verify_slip', [$this, 'verify_slip']);
}
public function verify_slip()
{
check_ajax_referer('easyslip_nonce', 'nonce');
$order_id = sanitize_text_field($_POST['order_id']);
$order = wc_get_order($order_id);
if (!$order) {
wp_send_json_error(['message' => 'Order not found']);
}
if (empty($_FILES['slip'])) {
wp_send_json_error(['message' => 'No slip image provided']);
}
$file = $_FILES['slip'];
$expected_amount = $order->get_total();
$result = $this->call_api($file['tmp_name'], [
'remark' => "WC-{$order_id}",
'matchAmount' => $expected_amount,
'checkDuplicate' => true,
]);
if (!$result['success']) {
wp_send_json_error(['message' => $result['error']['message']]);
}
$data = $result['data'];
if ($data['isDuplicate']) {
wp_send_json_error(['message' => 'Slip already used']);
}
if (!$data['isAmountMatched']) {
wp_send_json_error([
'message' => sprintf(
'Amount mismatch: expected %.2f, got %.2f',
$expected_amount,
$data['rawSlip']['amount']['amount']
),
]);
}
// Update order status
$order->payment_complete($data['rawSlip']['transRef']);
$order->add_order_note(sprintf(
'Payment verified via EasySlip. Trans: %s',
$data['rawSlip']['transRef']
));
wp_send_json_success([
'message' => 'Payment verified',
'transRef' => $data['rawSlip']['transRef'],
]);
}
private function call_api(string $file_path, array $options): array
{
$ch = curl_init();
$post_data = [
'image' => new CURLFile($file_path),
];
foreach ($options as $key => $value) {
$post_data[$key] = is_bool($value) ? ($value ? 'true' : 'false') : $value;
}
curl_setopt_array($ch, [
CURLOPT_URL => 'https://api.easyslip.com/v2/verify/bank',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $this->api_key,
],
CURLOPT_POSTFIELDS => $post_data,
]);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
}
new EasySlipVerify();Error Handling
php
<?php
function verifySlipWithRetry(
EasySlipClient $client,
string $payload,
int $maxRetries = 3
): array {
$lastError = null;
for ($attempt = 1; $attempt <= $maxRetries; $attempt++) {
try {
$result = $client->verifyByPayload($payload, [
'checkDuplicate' => true,
]);
if ($result['success']) {
return $result['data'];
}
$errorCode = $result['error']['code'];
switch ($errorCode) {
case 'QUOTA_EXCEEDED':
throw new Exception('API quota exceeded');
case 'SLIP_NOT_FOUND':
throw new Exception('Invalid slip');
case 'API_SERVER_ERROR':
if ($attempt < $maxRetries) {
sleep($attempt); // Exponential backoff
continue;
}
throw new Exception('Server temporarily unavailable');
default:
throw new Exception($result['error']['message']);
}
} catch (Exception $e) {
$lastError = $e;
if ($attempt === $maxRetries) {
throw $e;
}
}
}
throw $lastError ?? new Exception('Max retries exceeded');
}