Jump to content

Clover integration


Recommended Posts

So I've been trying to figure this out for a while now but haven't been able to fix it. My payment processor is Clover, which there isn't a pre-built WHMCS gateway for. So I am attempting to make my own but I'm doing something wrong but I can't figure out what it is that I'm doing wrong. I will say that I am new to this.

I created a clovergateway.php file in the modules/gateways directory and a clovergateway.php file in the modules/gateways/callbacks directory. 

Here's the code from the clovergateway.php file in the modules/gateways directory:

<?php

if (!defined("WHMCS")) {
    die("This file cannot be accessed directly");
}

function clovergateway_MetaData()
{
    return [
        'DisplayName' => 'Clover Gateway',
        'APIVersion' => '1.0',
        'DisableLocalCredtCardInput' => true,
        'TokenisedStorage' => true,
    ];
}

function clovergateway_config()
{
    return [
        'FriendlyName' => [
            'Type' => 'System',
            'Value' => 'Clover Gateway',
        ],
        'apiKey' => [
            'FriendlyName' => 'API Key',
            'Type' => 'text',
            'Size' => '25',
            'Default' => '',
            'Description' => 'Enter your Clover API Key here.',
        ],
        'merchantId' => [
            'FriendlyName' => 'Merchant ID',
            'Type' => 'text',
            'Size' => '25',
            'Default' => '',
            'Description' => 'Enter your Clover Merchant ID here.',
        ],
        'publicKey' => [
            'FriendlyName' => 'Public Key',
            'Type' => 'text',
            'Size' => '25',
            'Default' => '',
            'Description' => 'Enter your Clover Public Key here.',
        ],
    ];
}
function clovergateway_remoteinput($params)
{
    $tokenForm = <<<HTML
<form id="paymentfrm" method="post" action="{$params['systemurl']}/creditcard.php">
    <input type="hidden" name="invoiceid" value="{$params['invoiceid']}" />
    <input type="hidden" name="gatewayid" value="{$params['gatewayid']}" />

    <label for="cardNumber">Card Number</label>
    <input type="text" id="cardNumber" />

    <label for="cardExpiryMonth">Expiry Month</label>
    <input type="text" id="cardExpiryMonth" />

    <label for="cardExpiryYear">Expiry Year</label>
    <input type="text" id="cardExpiryYear" />

    <label for="cardCVV">CVV</label>
    <input type="text" id="cardCVV" />

    <button type="button" id="submitButton">Submit</button>
</form>
<script src="https://checkout.clover.com/sdk.js"></script>
<script>
    // Replace with your public key
    const publicKey = "{$params['publicKey']}";
    const clover = new Clover(publicKey);
    const elements = clover.elements();

    document.getElementById('submitButton').addEventListener('click', function() {
        clover.createToken({
            cardNumber: document.getElementById('cardNumber').value,
            expMonth: document.getElementById('cardExpiryMonth').value,
            expYear: document.getElementById('cardExpiryYear').value,
            cvv: document.getElementById('cardCVV').value
        }).then(function(response) {
            document.getElementById('gatewayid').value = response.token;
            document.getElementById('paymentfrm').submit();
        }).catch(function(error) {
            // Handle the error
            alert(error.message);
        });
    });
</script>
HTML;

    return $tokenForm;
}


function clovergateway_storeremote($params)
{
    // Store the remote token and return success
    return [
        'success' => true,
        'gatewayid' => $params['card_token'],
    ];
}

function clovergateway_capture($params)
{
    // Fetch the API Key, Merchant ID, and other required parameters
    $apiKey = $params['apiKey'];
    $merchantId = $params['merchantId'];
    $cloverApiUrl = "https://api.clover.com"; // Replace with the appropriate API URL

    // Fetch the card details and invoice amount
    $token = $params['gatewayid'];
    $amount = $params['amount'];

    // Set the required headers for Clover API requests
    $headers = [
        "Content-Type: application/json",
        "Authorization: Bearer {$apiKey}"
    ];

    // Create the charge
    $url = "{$cloverApiUrl}/v1/merchant/{$merchantId}/charges";
    $method = "POST";
    $data = [
        'token' => $token,
        'amount' => $amount * 100 // Convert to cents
    ];

    $response = cloverApiRequest($url, $method, $headers, $data);

    // Check if the charge was successful
    if (isset($response['id'])) {
        return [
            'status' => 'success',
            'transid' => $response['id'],
            'rawdata' => $response,
        ];
    } else {
        return [
            'status' => 'error',
            'rawdata' => $response,
        ];
    }
}

function cloverApiRequest($url, $method, $headers, $data)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    $response = curl_exec($ch);

    if (curl_errno($ch)) {
        throw new Exception('Curl error: ' . curl_error($ch));
    }

    curl_close($ch);

    return json_decode($response, true);
}

Here's the code from the clovergateway.php file in the modules/gateways/callbacks directory:

<?php

use WHMCS\Database\Capsule;

require '../../../init.php';
require '../../../includes/gatewayfunctions.php';
require '../../../includes/invoicefunctions.php';

$gatewayModuleName = basename(__FILE__, '.php');

$gatewayParams = getGatewayVariables($gatewayModuleName);

if (!$gatewayParams['type']) {
    die('Module not activated');
}

$invoiceId = $_POST['invoiceid'];
$gatewayId = $_POST['gatewayid'];

$invoiceData = Capsule::table('tblinvoices')
    ->where('id', $invoiceId)
    ->first();

$userId = $invoiceData->userid;

$success = checkCbInvoiceID($invoiceId, $gatewayParams['name']);

if ($success) {
    $result = Capsule::table('tblclients')
        ->where('id', $userId)
        ->update([
            'gatewayid' => $gatewayId,
        ]);

    header('Location: ' . $gatewayParams['systemurl'] . '/clientarea.php?action=invoices');
} else {
    header('Location: ' . $gatewayParams['systemurl'] . '/clientarea.php?action=invoices&status=error');
}

I was able to activate and configure the module with no issue but when I went to try testing it on the client side by trying to pay an invoice using it, that's when the issues began. When you click the "Pay Now" button on the invoice page, you are taken to another page where you are prompted to enter the payment info but on that page, there is a weird embed of the page underneath the payment form. The payment form doesn't work either. Pressing the submit button doesn't do anything.

I have attached a screenshot and a log file from the DevTools console.

Here's a link to the Clover Docs

Any assistance would be greatly appreciated  

Screenshot 2023-05-07 135910.png

whmcsdev.levineswebhosting.com-1683482428215.log

Link to comment
Share on other sites

  • 9 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use & Guidelines and understand your posts will initially be pre-moderated