Payment Addon Development

Hi,

Sorry I can't post this topic to Developers' Corner.

I'm going to code an e-wallet payment gateway for my own multi-vendor page by myself. Are there any docs, workflows or tutorials more detail than the official one?

Thank you so much!

Did you check the following article?

https://docs.cs-cart.com/latest/developer_guide/addons/tutorials/payment_processor_addon.html

Yes, I did and read code of another addons too. I think i should get to work before asking. Thanks

Hi,

I use fn_create_payment_form to submit a request but get problem with parsing body. Here my code:

use Tygh\Registry;

defined(‘BOOTSTRAP’) or die(‘Access denied’);

// Here are two different contexts for running the script.
if (defined(‘PAYMENT_NOTIFICATION’)) {

fn_print_r("Processing the answer");

} else {

$secretKey = $processor_data['processor_params']['secret_key'];
$endpoint = "https://test-payment.mm.vn/gw_payment/transactionProcessor";

$partnerCode = $processor_data['processor_params']['partner_code'];
$accessKey = $processor_data['processor_params']['access_key'];
$orderId = $order_id;
$orderInfo = "Test";
$amount = $order_info['total'] * 23000;
$returnUrl = fn_url("payment_notification.invoice?payment=mm&order_id=$order_id", AREA, 'https');
$notifyUrl = fn_url("payment_notification.notify?payment=mm&order_id=$order_id", AREA, 'https');

$requestId = time() . "";
$requestType = "captureMMWallet";
$extraData = "merchantName=MM_Partner";

$rawHash = "partnerCode=" . $partnerCode . "&accessKey=" . $accessKey . "&requestId=" . $requestId . "&amount=" . $amount . "&orderId=" . $orderId . "&orderInfo=" . $orderInfo . "&returnUrl=" . $returnUrl . "¬ifyUrl=" . $notifyUrl . "&extraData=" . $extraData;

$signature = hash_hmac("sha256", $rawHash, $secretKey);
$post_data = array(
    'partnerCode' => $partnerCode,
    'accessKey' => $accessKey,
    'requestId' => $requestId,
    'amount' => $amount,
    'orderId' => $orderId,
    'orderInfo' => $orderInfo,
    'returnUrl' => $returnUrl,
    'notifyUrl' => $notifyUrl,
    'extraData' => $extraData,
    'requestType' => $requestType,
    'signature' => $signature
);

//fn_print_r($post_data);
//fn_print_r($signature);
fn_create_payment_form($endpoint, $post_data, 'MM');

exit;

}

My error

{
    "request": {
        "data": "...",
        "timeout": 90,
        "headers": {
            "headers": {
                "sec-fetch-mode": "navigate",
                "content-length": "508",
                "referer": "http://xxx.vn/index.php?dispatch=checkout.place_order",
                "sec-fetch-site": "cross-site",
                "x-forwarded-proto": "http",
                "accept-language": "en-US,en;q=0.9",
                "cookie": "JSESSIONID=E1EDEE9D138CAD48510C482A2A498F76",
                "origin": "http://xxx.vn",
                "x-forwarded-port": "80",
                "x-forwarded-for": "xxx.xxx.xxx.xxx, xxx.xx.x.xx",
                "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
                "x-real-ip": "xxx.xx.x.xx",
                "x-forwarded-host": "test-payment.momo.vn",
                "host": "test-payment.momo.vn",
                "x-powered-by": "momo.vn",
                "upgrade-insecure-requests": "1",
                "connection": "keep-alive",
                "content-type": "application/x-www-form-urlencoded",
                "x-forwarded-by": "xxx.xx.x.xx:443",
                "cache-control": "max-age=0",
                "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36 OPR/68.0.3618.173",
                "sec-fetch-dest": "document"
            }
        }
    },
    "errorCode": 59,
    "message": "Error parsing body to Json object. Accepted Content-Type: application/json; charset=UTF-8. Check request headers and body",
    "localMessage": "Yêu cầu không hợp lệ"
}

Please help. Thanks so much.

Check documentation for developers. Looks like you should send body in json format, not separate fields (partnerCode, accessKey, etc)

Check documentation for developers. Looks like you should send body in json format, not separate fields (partnerCode, accessKey, etc)

Could I use fn_create_payment_form to send Json or I need to override it? Or use another function? My payment processor is "callback=N". Thanks

I'm using cUrl instead of fn_create_payment_form. Is it good? Thanks

$post_data = json_encode($data);

$ch = curl_init($endpoint);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(‘Content-Type:application/json’));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

// for localhost
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);

$result = curl_exec($ch);
curl_close($ch);

$arrayResult = json_decode($result, true);

header(‘Content-type: text/html; charset=utf-8’);
header('Location: ’ . $arrayResult[‘payUrl’]);

exit;

It is better to use Http:get or Http::get default methods. Some integrated payment systems use it

Hi eComLabs,

I get "404 Page not found" with the return url

http://sivin-7f251c0d.localhost.run/index.php?dispatch=payment_notification.invoice&payment=Momo&order_id=101&partnerCode=...

My payment_notification code:

if (defined('PAYMENT_NOTIFICATION')) {
if (!fn_check_payment_script(MOMO_PROCESSOR_SCRIPT, $order_id)) {
    return array(CONTROLLER_STATUS_DENIED);
}

$order_id = $_REQUEST['order_id'];
$pp_response = fn_momo_response_processing($_REQUEST, $processor_data['processor_params']['secret_key']);
    
if ($mode == 'notify') {

    fn_change_order_status($order_id, $pp_response["order_status"], '', true);
    exit();

} elseif ($mode == 'invoice') {

    fn_finish_payment($order_id, $pp_response, false);
    fn_order_placement_routines('route', $order_id);
    exit();
}

}

Thanks for your help :wub:

If your payment script is called my_script.php, URL should contain the following parameter

...&payment=my_script&...

If your payment script is called my_script.php, URL should contain the following parameter

...&payment=my_script&...

I already changed payment to my script ...&payment=momo_processor&... but still doesn't work. Please see the attachment. Thanks

screenshot.png

then replace

if (!fn_check_payment_script(MOMO_PROCESSOR_SCRIPT, $order_id)) {

with

if (!fn_check_payment_script('momo_processor.php', $_REQUEST['order_id'])) {

then replace

if (!fn_check_payment_script(MOMO_PROCESSOR_SCRIPT, $order_id)) {

with

if (!fn_check_payment_script('momo_processor.php', $_REQUEST['order_id'])) {

Thank you so much. It works. I passed an empty order_id.

There are new problem:

- I can't get $processor_data when PAYMENT_NOTIFICATION defined.

- fn_order_placement_routines('route', $order_id) doesn't clear cart and not redirect to order completed page but come back to checkout page.

Thank you so much. It works. I passed an empty order_id.

There are new problem:

- I can't get $processor_data when PAYMENT_NOTIFICATION defined.

- fn_order_placement_routines('route', $order_id) doesn't clear cart and not redirect to order completed page but come back to checkout page.

My bad, fn_order_placement_routines('route', $order_id) work when $pp_response['order_status'] = 'P'

There are new problem:

- I can't get $processor_data when PAYMENT_NOTIFICATION defined.

$order_info = fn_get_order_info($_REQUEST['order_id']);
$processor_data = fn_get_processor_data($order_info['payment_id']);