Implement Stripe: สร้างคลาส StripePayment
ในบทที่แล้ว เราได้กำหนด Interface ที่ชื่อว่า PaymentGatewayInterface ซึ่งเป็นเหมือนพิมพ์เขียวสำหรับ Payment Gateway ทุกประเภท ในบทนี้ เราจะมาสร้างคลาส StripePayment ที่จะ Implement Interface นี้ และเชื่อมต่อกับ Stripe API เพื่อให้สามารถประมวลผลการชำระเงินผ่าน Stripe ได้จริง
ติดตั้ง Stripe PHP Library
ก่อนอื่น เราต้องติดตั้ง Stripe PHP Library เพื่อให้เราสามารถใช้งาน Stripe API ได้ง่ายขึ้น สามารถทำได้โดยใช้ Composer ดังนี้:
composer require stripe/stripe-php
หลังจากรันคำสั่งนี้ Composer จะดาวน์โหลดและติดตั้ง Stripe PHP Library ลงในโปรเจ็กต์ของเรา
Implement PaymentGatewayInterface
ตอนนี้เรามาสร้างคลาส StripePayment และ Implement PaymentGatewayInterface กัน:
<?php
require_once 'PaymentGatewayInterface.php';
class StripePayment implements PaymentGatewayInterface {
private $apiKey;
public function __construct(string $apiKey) {
$this->apiKey = $apiKey;
\Stripe\Stripe::setApiKey($this->apiKey); // กำหนด API Key ให้กับ Stripe PHP Library
}
public function charge(float $amount, string $token): string {
try {
$charge = \Stripe\Charge::create([
'amount' => $amount * 100, // Stripe ใช้หน่วยเป็น cents
'currency' => 'thb', // กำหนดสกุลเงิน
'source' => $token, // Token ที่ได้จาก Stripe.js หรือ Stripe Elements
'description' => 'Charge for example product', // คำอธิบายรายการ
]);
return $charge->id; // คืนค่า Charge ID
} catch (\Stripe\Exception\CardException $e) {
// ข้อผิดพลาดเกี่ยวกับบัตรเครดิต
throw new \Exception("Card Error: " . $e->getMessage());
} catch (\Stripe\Exception\RateLimitException $e) {
// ข้อจำกัดด้าน Rate Limit
throw new \Exception("Rate Limit Error: " . $e->getMessage());
} catch (\Stripe\Exception\InvalidRequestException $e) {
// ข้อมูลไม่ถูกต้อง
throw new \Exception("Invalid Request Error: " . $e->getMessage());
} catch (\Stripe\Exception\AuthenticationException $e) {
// การยืนยันตัวตนล้มเหลว
throw new \Exception("Authentication Error: " . $e->getMessage());
} catch (\Stripe\Exception\ApiConnectionException $e) {
// ไม่สามารถเชื่อมต่อกับ Stripe API
throw new \Exception("API Connection Error: " . $e->getMessage());
} catch (\Stripe\Exception\ApiErrorException $e) {
// ข้อผิดพลาดอื่นๆ จาก Stripe API
throw new \Exception("Stripe API Error: " . $e->getMessage());
} catch (\Exception $e) {
// ข้อผิดพลาดทั่วไป
throw new \Exception("An unexpected error occurred: " . $e->getMessage());
}
}
public function refund(string $chargeId): bool {
try {
$refund = \Stripe\Refund::create([
'charge' => $chargeId,
]);
return $refund->status === 'succeeded'; // คืนค่า true หากการคืนเงินสำเร็จ
} catch (\Stripe\Exception\CardException $e) {
// ข้อผิดพลาดเกี่ยวกับบัตรเครดิต
throw new \Exception("Card Error: " . $e->getMessage());
} catch (\Stripe\Exception\RateLimitException $e) {
// ข้อจำกัดด้าน Rate Limit
throw new \Exception("Rate Limit Error: " . $e->getMessage());
} catch (\Stripe\Exception\InvalidRequestException $e) {
// ข้อมูลไม่ถูกต้อง
throw new \Exception("Invalid Request Error: " . $e->getMessage());
} catch (\Stripe\Exception\AuthenticationException $e) {
// การยืนยันตัวตนล้มเหลว
throw new \Exception("Authentication Error: " . $e->getMessage());
} catch (\Stripe\Exception\ApiConnectionException $e) {
// ไม่สามารถเชื่อมต่อกับ Stripe API
throw new \Exception("API Connection Error: " . $e->getMessage());
} catch (\Stripe\Exception\ApiErrorException $e) {
// ข้อผิดพลาดอื่นๆ จาก Stripe API
throw new \Exception("Stripe API Error: " . $e->getMessage());
} catch (\Exception $e) {
// ข้อผิดพลาดทั่วไป
throw new \Exception("An unexpected error occurred: " . $e->getMessage());
}
}
}
คำอธิบายโค้ด:
require_once 'PaymentGatewayInterface.php';: ทำการ include ไฟล์ Interface ที่เราสร้างไว้ในบทที่แล้วclass StripePayment implements PaymentGatewayInterface: ประกาศคลาสStripePaymentและบอกว่า Implement InterfacePaymentGatewayInterfaceprivate $apiKey;: ประกาศตัวแปร$apiKeyเพื่อเก็บ Stripe API Keypublic function __construct(string $apiKey): Constructor ของคลาส รับค่า API Key และกำหนดให้กับตัวแปร$apiKeyและทำการกำหนด API Key ให้กับ Stripe PHP Library โดยใช้\Stripe\Stripe::setApiKey($this->apiKey);public function charge(float $amount, string $token): string: ฟังก์ชันchargeที่ Implement จาก Interface รับค่า$amount(จำนวนเงิน) และ$token(Token ที่ได้จาก Stripe.js หรือ Stripe Elements) และทำการเรียก Stripe API เพื่อประมวลผลการชำระเงินpublic function refund(string $chargeId): bool: ฟังก์ชันrefundที่ Implement จาก Interface รับค่า$chargeId(Charge ID ที่ได้จากการชำระเงิน) และทำการเรียก Stripe API เพื่อทำการคืนเงินtry...catch: ใช้try...catchเพื่อจัดการกับข้อผิดพลาดที่อาจเกิดขึ้นระหว่างการเรียก Stripe API ข้อผิดพลาดที่อาจเกิดขึ้น เช่น ข้อผิดพลาดเกี่ยวกับบัตรเครดิต, ข้อจำกัดด้าน Rate Limit, ข้อมูลไม่ถูกต้อง, การยืนยันตัวตนล้มเหลว, ไม่สามารถเชื่อมต่อกับ Stripe API และข้อผิดพลาดอื่นๆ จาก Stripe API$amount * 100: Stripe ใช้หน่วยเป็น cents ดังนั้นเราต้องคูณจำนวนเงินด้วย 100'currency' => 'thb': กำหนดสกุลเงินเป็น THB (บาทไทย)'source' => $token: กำหนด Token ที่ได้จาก Stripe.js หรือ Stripe Elements ให้กับsourcereturn $charge->id;: คืนค่า Charge ID หากการชำระเงินสำเร็จreturn $refund->status === 'succeeded';: คืนค่าtrueหากการคืนเงินสำเร็จ
เชื่อมต่อกับ Stripe API
ในการเชื่อมต่อกับ Stripe API เราต้องใช้ API Key ซึ่งสามารถหาได้จาก Stripe Dashboard (https://dashboard.stripe.com/apikeys) อย่าลืมเก็บ API Key ของคุณไว้เป็นความลับ และอย่าเปิดเผยให้ใครทราบ
ข้อควรระวัง: ใช้ Secret Key เฉพาะฝั่ง Server เท่านั้น ห้ามนำไปใช้ใน Client Side (JavaScript) เด็ดขาด เพราะอาจทำให้ API Key ของคุณถูกขโมยได้
ตัวอย่างการใช้งาน:
<?php
require_once 'StripePayment.php';
// แทนที่ YOUR_STRIPE_SECRET_KEY ด้วย Secret Key ของคุณ
$stripeApiKey = 'YOUR_STRIPE_SECRET_KEY';
$stripePayment = new StripePayment($stripeApiKey);
try {
// แทนที่ 100 ด้วยจำนวนเงินที่ต้องการชำระ (บาท)
// แทนที่ tok_xxxxxxxxxxxxxxxxxxxxxx ด้วย Token ที่ได้จาก Stripe.js หรือ Stripe Elements
$chargeId = $stripePayment->charge(100, 'tok_xxxxxxxxxxxxxxxxxxxxxx');
echo "Payment successful! Charge ID: " . $chargeId . "<br>";
// ทดลองคืนเงิน
$refundSuccessful = $stripePayment->refund($chargeId);
if ($refundSuccessful) {
echo "Refund successful!";
} else {
echo "Refund failed!";
}
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}
คำอธิบายโค้ด:
$stripeApiKey = 'YOUR_STRIPE_SECRET_KEY';: แทนที่YOUR_STRIPE_SECRET_KEYด้วย Secret Key ของคุณ$stripePayment = new StripePayment($stripeApiKey);: สร้าง Instance ของคลาสStripePaymentโดยส่ง API Key ไปให้ Constructor$chargeId = $stripePayment->charge(100, 'tok_xxxxxxxxxxxxxxxxxxxxxx');: เรียกฟังก์ชันchargeเพื่อประมวลผลการชำระเงิน โดยส่งจำนวนเงิน (100 บาท) และ Token ที่ได้จาก Stripe.js หรือ Stripe Elements$refundSuccessful = $stripePayment->refund($chargeId);: เรียกฟังก์ชันrefundเพื่อทำการคืนเงิน โดยส่ง Charge ID ที่ได้จากการชำระเงินtry...catch: ใช้try...catchเพื่อจัดการกับข้อผิดพลาดที่อาจเกิดขึ้น
ข้อผิดพลาดที่พบบ่อย:
- Invalid API Key: ตรวจสอบให้แน่ใจว่า API Key ที่คุณใช้ถูกต้อง
- Invalid Token: ตรวจสอบให้แน่ใจว่า Token ที่คุณใช้ถูกต้อง และสร้างขึ้นมาสำหรับ Stripe API
- Card Declined: บัตรเครดิตถูกปฏิเสธ ตรวจสอบข้อมูลบัตรเครดิต และลองใหม่อีกครั้ง
- Insufficient Funds: บัตรเครดิตมีเงินไม่พอ ตรวจสอบวงเงินในบัตรเครดิต
- Rate Limit Exceeded: จำนวน Request เกิน Limit ที่ Stripe กำหนด ลองเว้นช่วงเวลาแล้วลองใหม่อีกครั้ง
ในบทนี้ เราได้สร้างคลาส StripePayment ที่ Implement PaymentGatewayInterface และเชื่อมต่อกับ Stripe API เพื่อประมวลผลการชำระเงิน ในบทถัดไป เราจะมาสร้างคลาส PayPalPayment ที่จะ Implement PaymentGatewayInterface และเชื่อมต่อกับ PayPal API