'Sample Remote Input Gateway Module', 'APIVersion' => '1.1', // Use API Version 1.1 ]; } function wph_remoteinputgateway_config() { return [ // the friendly display name for a payment gateway should be // defined here for backwards compatibility 'FriendlyName' => [ 'Type' => 'System', 'Value' => 'Sample Remote Input Gateway Module', ], // a text field type allows for single line text input 'apiUsername' => [ 'FriendlyName' => 'API Username', 'Type' => 'text', 'Size' => '25', 'Default' => '', 'Description' => 'Enter your API Username here', ], // a password field type allows for masked text input 'apiPassword' => [ 'FriendlyName' => 'API Password', 'Type' => 'text', 'Size' => '25', 'Default' => '', 'Description' => 'Enter your API Password here', ], // a password field type allows for masked text input 'apiDomain' => [ 'FriendlyName' => 'API Domain', 'Type' => 'text', 'Size' => '25', 'Default' => '', 'Description' => 'Enter your API Domain here', ], // the yesno field type displays a single checkbox option 'testMode' => [ 'FriendlyName' => 'Test Mode', 'Type' => 'yesno', 'Description' => 'Tick to enable test mode', ], ]; } function GetApi($url, $param){ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json')); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($param)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $response = curl_exec($ch); curl_close($ch); return $response; } /** * No local credit card input. */ function wph_remoteinputgateway_nolocalcc() {} /** * Capture payment. * * Called when a payment is requested to be processed and captured. * * The CVV number parameter will only be present for card holder present * transactions and when made against an existing stored payment token * where new card data has not been entered. * * @param array $params Payment Gateway Module Parameters * * @see https://developers.whmcs.com/payment-gateways/remote-input-gateway/ * * @return array */ function wph_remoteinputgateway_capture($params) { my_log_errors('Capture start'); $remoteGatewayToken = $params['gatewayid']; $cardCvv = $params['cccvv']; // Card Verification Value // Gateway Configuration Parameters $merchantAccount = $params['apiUsername']; $secretKey = $params['apiPassword']; $merchantDomainName = $params['apiDomain']; // Client Parameters $clientId = $params['clientdetails']['id']; $email = $params['clientdetails']['email']; $phone = $params['clientdetails']['phonenumber']; // Invoice Parameters $invoice_id = $params['invoiceid']; $merchantTransactionType = 'SALE'; $description = "Invoice#$invoice_id"; $amount = (string)$params['amount']; // System Parameters $systemUrl = $params['systemurl']; $returnUrl = $params['returnurl']; $langPayNow = $params['langpaynow']; $moduleName = $params['paymentmethod']; $url = 'https://api.pay.com/api'; //Post fields $postFields = [ 'token' => $remoteGatewayToken, 'cvv' => $cardCvv, 'invoice_number' => $invoice_id, 'amount' => $amount, 'currency' => 'UAH', ]; // A token is required for a remote input gateway capture attempt if (!$remoteGatewayToken) { my_log_errors('No Remote Token'); return [ 'status' => 'declined', 'decline_message' => 'No Remote Token', ]; } else { my_log_errors('Remote Token ok'); } /************************************* /API *********************************************************/ // Perform API call to initiate capture. my_log_errors('Api call start'); $json = GetApi($url,$postfields); $request = json_decode($json); $orderReference = $request->orderReference; $invoice_id = $request->invoice_id; $customer_id = $request->customer_id; $transaction_id = $request->orderReference; $payment_amount = $request->amount; $payment_fee = $request->fee; $sign_string = "$request->merchantAccount;.......$request->reasonCode"; $sign = hash_hmac('md5', $sign_string, $secretKey); $success = false; $response = [ 'success' => false, 'transaction_id' => '', 'fee' => 0, 'token' => '', 'decline_reason' => 'Unknown Error' ]; if ($request->merchantSignature == $sign) { $success = true; $response_status = 'accept'; $action = 'payment'; } else { $response_status = 'Hash Verification Failure'; $response = [ 'success' => false, 'transaction_id' => $transaction_id, 'fee' => $payment_fee, 'token' => $remoteGatewayToken, 'decline_reason' => $response_status ]; } if ($request->transactionStatus != 'Approved' && $request->reasonCode != 1100) { $success = false; $transaction_status = $request->reason; $response = [ 'success' => false, 'transaction_id' => $transaction_id, 'fee' => $payment_fee, 'token' => $remoteGatewayToken, 'decline_reason' => $transaction_status ]; } if ($success) { $invoice_id = checkCbInvoiceID($invoice_id, $gatewayParams['name']); checkCbTransID($transaction_id); logTransaction($gatewayParams['name'], (array)$request, $transaction_status); $invoice_res = addInvoicePayment( $invoice_id, $transaction_id, $payment_amount, $payment_fee, $gatewayModuleName ); } if ($invoice_res == 'success ') { $response = [ 'success' => true, 'transaction_id' => $transaction_id, 'fee' => $payment_fee, 'token' => $remoteGatewayToken, ]; } else { $response = [ 'success' => false, 'transaction_id' => $transaction_id, 'fee' => $payment_fee, 'token' => $remoteGatewayToken, 'decline_reason' => 'addInvoicePayment returned error', ]; } /************************************* /API *********************************************************/ if ($response['success']) { return [ // 'success' if successful, otherwise 'declined', 'error' for failure 'status' => 'success', // The unique transaction id for the payment 'transid' => $response['transaction_id'], // Optional fee amount for the transaction 'fee' => $response['fee'], // Return only if the token has updated or changed 'gatewayid' => $response['token'], // Data to be recorded in the gateway log - can be a string or array 'rawdata' => $response, ]; } return [ // 'success' if successful, otherwise 'declined', 'error' for failure 'status' => 'declined', // For declines, a decline reason can optionally be returned 'declinereason' => $response['decline_reason'], // Data to be recorded in the gateway log - can be a string or array 'rawdata' => $response, ]; } /** * Remote input. * @return array */ function wph_remoteinputgateway_remoteinput($params) { $postFields = [ 'token' => $remoteGatewayToken, 'cvv' => $cardCvv, 'invoice_number' => $invoice_id, 'amount' => $amount, 'currency' => 'UAH', ]; //$htmlOutput = '
'; foreach ($postfields as $k => $v) { $htmlOutput .= ''; } // This is a working example which posts to the file: demo/remote-iframe-demo.php return ' ' . $htmlOutput . '
'; } /** * Remote update. * @return array */ function wph_remoteinputgateway_remoteupdate($params) { return << Updating your card is not possible. Please create a new Pay Method to make changes. HTML; } /** * Admin status message. * * Called when an invoice is viewed in the admin area. * * @param array $params Payment Gateway Module Parameters. * * @return array */ function wph_remoteinputgateway_adminstatusmsg($params) { // Gateway Configuration Parameters $apiUsername = $params['apiUsername']; $apiPassword = $params['apiPassword']; $testMode = $params['testMode']; // Invoice Parameters $remoteGatewayToken = $params['gatewayid']; if ($remoteGatewayToken) { return [ 'type' => 'info', 'title' => 'Token Gateway Profile', 'msg' => 'This customer has a Remote Token storing their card' . ' details for automated recurring billing with ID ' . $remoteGatewayToken, ]; } }