281 lines
10 KiB
PHP
281 lines
10 KiB
PHP
<?php
|
|
|
|
namespace App\Extensions\Gateways\ReverePayments;
|
|
|
|
use App\Classes\Extensions\Gateway;
|
|
use App\Helpers\ExtensionHelper;
|
|
use Illuminate\Http\Request;
|
|
use Exception;
|
|
|
|
class ReverePayments extends Gateway
|
|
{
|
|
public function getMetadata()
|
|
{
|
|
return [
|
|
'display_name' => 'ReverePayments',
|
|
'version' => '1.0.0',
|
|
'author' => 'Paymenter',
|
|
'website' => 'https://paymenter.org',
|
|
];
|
|
}
|
|
|
|
public function getUrl($total, $products, $orderId, $client = null)
|
|
{
|
|
$apiKey = ExtensionHelper::getConfig('ReverePayments', 'revere_api_key');
|
|
$publicCheckoutKey = ExtensionHelper::getConfig('ReverePayments', 'revere_public_checkout_key');
|
|
$publicCheckoutKey = 'checkout_public_R7Kgf3GyG9Bru9W5vhR293qd22U8rn8H';
|
|
$isTestMode = ExtensionHelper::getConfig('ReverePayments', 'revere_test_mode');
|
|
|
|
// TODO: find out what the sandbox url is
|
|
$baseRevereApiUrl = $isTestMode ? 'https://api.sandbox.reverepayments.dev' : 'https://api.reverepayments.dev';
|
|
$baseCartUrl = $isTestMode ? 'https://secure.reverepayments.com' : 'https://secure.reverepayments.com';
|
|
|
|
|
|
$lineItems = [];
|
|
foreach ($products as $product) {
|
|
// Ensure the product exists in Revere Payments
|
|
// This will create or update the product if needed
|
|
$this->createOrUpdateProduct($product);
|
|
|
|
// Use the generateProductSku method for consistency
|
|
$sku = $this->generateProductSku($product);
|
|
|
|
$lineItems[] = [
|
|
'sku' => $sku,
|
|
'quantity' => $product->quantity,
|
|
];
|
|
}
|
|
|
|
$curl = curl_init();
|
|
|
|
$data = [
|
|
'lineItems' => $lineItems,
|
|
'receipt' => [
|
|
'showReceipt' => true
|
|
],
|
|
'key' => $publicCheckoutKey,
|
|
];
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://secure.reverepayments.com/api/v4/cart',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'POST',
|
|
CURLOPT_POSTFIELDS => json_encode($data),
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Accept: application/json, text/plain, */*',
|
|
'Accept-Encoding: gzip, deflate, br, zstd',
|
|
'Accept-Language: en-US,en;q=0.9',
|
|
'Cache-Control: no-cache',
|
|
'Connection: keep-alive',
|
|
'Content-Type: application/json',
|
|
'Origin: null',
|
|
'Pragma: no-cache',
|
|
'Sec-Fetch-Dest: empty',
|
|
'Sec-Fetch-Mode: cors',
|
|
'Sec-Fetch-Site: cross-site',
|
|
'Sec-GPC: 1',
|
|
'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36',
|
|
'sec-ch-ua: "Chromium";v="134", "Not:A-Brand";v="24", "Brave";v="134"',
|
|
'sec-ch-ua-mobile: ?0',
|
|
'sec-ch-ua-platform: "macOS"'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
|
curl_close($curl);
|
|
|
|
if ($httpCode < 200 || $httpCode >= 300) {
|
|
throw new Exception('Failed to create Revere payment session: ' . $response);
|
|
}
|
|
|
|
$responseData = json_decode($response, true);
|
|
|
|
|
|
if (!isset($responseData['id'])) {
|
|
throw new Exception('Invalid response from Revere Payments API');
|
|
}
|
|
|
|
|
|
$redirectUrl = "https://collectcheckout.com/collect-checkout/?cartId=" . $responseData['id'];
|
|
|
|
return $redirectUrl;
|
|
}
|
|
|
|
public function webhook(Request $request)
|
|
{
|
|
$payload = $request->getContent();
|
|
$signature = $request->header('revere-signature');
|
|
$webhookSecret = ExtensionHelper::getConfig('ReverePayments', 'revere_webhook_secret');
|
|
|
|
// Verify webhook signature
|
|
$computedSignature = hash_hmac('sha256', $payload, $webhookSecret);
|
|
if (!hash_equals($computedSignature, $signature)) {
|
|
http_response_code(400);
|
|
exit('Invalid signature');
|
|
}
|
|
|
|
$event = json_decode($payload);
|
|
|
|
if ($event->type === 'payment.succeeded') {
|
|
$orderId = $event->data->metadata->order_id;
|
|
ExtensionHelper::paymentDone($orderId);
|
|
}
|
|
|
|
return response()->json(['success' => true]);
|
|
}
|
|
|
|
public function pay($total, $products, $orderId)
|
|
{
|
|
return $this->getUrl($total, $products, $orderId);
|
|
}
|
|
|
|
public function getConfig()
|
|
{
|
|
return [
|
|
[
|
|
'name' => 'revere_api_key',
|
|
'friendlyName' => 'Revere API Key',
|
|
'type' => 'text',
|
|
'description' => 'Your Revere Payments Checkout Public Key (starts with checkout_public_)',
|
|
'required' => true,
|
|
],
|
|
[
|
|
'name' => 'revere_webhook_secret',
|
|
'friendlyName' => 'Revere Webhook Secret',
|
|
'type' => 'text',
|
|
'description' => 'Your Revere Payments webhook secret for verifying webhook signatures',
|
|
'required' => true,
|
|
],
|
|
[
|
|
'name' => 'revere_public_checkout_key',
|
|
'friendlyName' => 'Revere Public Checkout Key',
|
|
'type' => 'text',
|
|
'description' => 'Your Revere Payments Checkout Public Key (starts with checkout_public_)',
|
|
'required' => true,
|
|
],
|
|
[
|
|
'name' => 'revere_test_mode',
|
|
'friendlyName' => 'Test Mode',
|
|
'type' => 'boolean',
|
|
'description' => 'Enable test mode to use sandbox environment',
|
|
'required' => false,
|
|
'default' => false,
|
|
]
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Generate a unique SKU for a product that can be reused
|
|
*
|
|
* @param object $product The product object
|
|
* @return string The generated SKU
|
|
*/
|
|
private function generateProductSku($product)
|
|
{
|
|
// Create a unique but consistent SKU based on product attributes
|
|
// Format: PM-{product_id}-{hash of product name}
|
|
return $product->name;
|
|
}
|
|
|
|
/**
|
|
* Create a product in Revere Payments system
|
|
*
|
|
* @param object $product The product to create
|
|
* @return array The created product data
|
|
*/
|
|
public function createOrUpdateProduct($product)
|
|
{
|
|
$apiKey = ExtensionHelper::getConfig('ReverePayments', 'revere_api_key');
|
|
$isTestMode = ExtensionHelper::getConfig('ReverePayments', 'revere_test_mode');
|
|
$baseRevereApiUrl = $isTestMode ? 'https://api.sandbox.reverepayments.dev' : 'https://api.reverepayments.dev';
|
|
$sku = $this->generateProductSku($product);
|
|
|
|
// Try to ADD the product and if it fails, update the product
|
|
$productData = [
|
|
'security_key' => $apiKey,
|
|
'products' => 'add_product',
|
|
'product_sku' => $sku,
|
|
'product_description' => $product->name ?? $product->description,
|
|
'product_cost' => $product->price,
|
|
'product_currency' => 'USD',
|
|
];
|
|
|
|
// Initialize cURL session
|
|
$ch = curl_init();
|
|
curl_setopt($ch, CURLOPT_URL, 'https://secure.reverepayments.com/api/transact.php');
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
curl_setopt($ch, CURLOPT_POST, true);
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
|
'Content-Type: application/x-www-form-urlencoded',
|
|
'Accept: application/json',
|
|
]);
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($productData));
|
|
|
|
// Execute cURL request
|
|
$response = curl_exec($ch);
|
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
curl_close($ch);
|
|
|
|
if ($httpCode < 200 || $httpCode >= 300) {
|
|
throw new Exception('Failed to create or update product in Revere Payments: ' . $response);
|
|
}
|
|
|
|
$responseData = [];
|
|
parse_str($response, $responseData);
|
|
|
|
$isSkuInUse = isset($responseData['responsetext']) && str_contains($responseData['responsetext'], "SKU already in use");
|
|
|
|
|
|
if ($isSkuInUse) {
|
|
return $responseData;
|
|
|
|
// Try to update the product if it already exists
|
|
// If the response text contains "SKU already in use", we need to update the sku
|
|
|
|
// $productData = [
|
|
// 'security_key' => $apiKey,
|
|
// 'products' => 'update_product',
|
|
// // 'product_id' => $responseData['product_id'],
|
|
// 'product_sku' => $sku,
|
|
// 'product_description' => $product->name ?? $product->description,
|
|
// 'product_cost' => $product->price,
|
|
// 'product_currency' => 'USD',
|
|
// ];
|
|
|
|
// // Initialize cURL session
|
|
// $ch = curl_init();
|
|
// curl_setopt($ch, CURLOPT_URL, 'https://secure.reverepayments.com/api/transact.php');
|
|
// curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
// curl_setopt($ch, CURLOPT_POST, true);
|
|
// curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
|
// 'Content-Type: application/x-www-form-urlencoded',
|
|
// 'Accept: application/json',
|
|
// ]);
|
|
// curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($productData));
|
|
|
|
// // Execute cURL request
|
|
// $response = curl_exec($ch);
|
|
// $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
// curl_close($ch);
|
|
|
|
// if ($httpCode < 200 || $httpCode >= 300) {
|
|
// throw new Exception('Failed to create or update product in Revere Payments: ' . $response);
|
|
// }
|
|
|
|
// $responseData = json_decode($response, true);
|
|
}
|
|
|
|
|
|
if (!isset($responseData['response']) || $responseData['response'] != "1") {
|
|
throw new Exception('Invalid response from Revere Payments API: ' . $responseData . '\n\n'. $response);
|
|
}
|
|
|
|
return $responseData;
|
|
}
|
|
} |