XF 2.0 Payment Profile Addon Needed help in understanding where i am doing wrong

Dnyan

Well-known member
I am Creating payment addon, after redirecting to payment provider i get error message stating checksum failed

here is the link to developer documentation https://developer.payumoney.com/redirect/

i did everything as per it, below is the code

PHP:
<?php

namespace XXX\XXXXXXXXXXXXXX\Payment;

use XF\Entity\PaymentProfile;
use XF\Entity\PurchaseRequest;
use XF\Http\Request;
use XF\Mvc\Controller;
use XF\Purchasable\Purchase;
use XF\Payment\AbstractProvider;
use XF\Payment\CallbackState;

class PayuMoney extends AbstractProvider
{
    public function getTitle()
    {
        return 'PayuMoney';
    }

    public function getApiEndpoint()
    {
       
            return 'https://test.payu.in/_payment';
       
       
    }

    public function getResultUrl()
    {
        return \XF::app()->options()->boardUrl . '/payment_callback.php?_xfProvider=payumoney';
    }

    public function verifyConfig(array &$options, &$errors = [])
    {
        if (empty($options['salt']))
        {
            $errors[] = \XF::phrase('you_must_provide_payu_salt_to_set_up_this_payment');

            return false;
        }

        if (empty($options['key']))
        {
            $errors[] = \XF::phrase('you_must_provide_payu_merchant_key_to_set_up_this_payment');

            return false;
        }

        if (empty($options['provider']))
        {
            $errors[] = \XF::phrase('you_must_provide_payu_provider_key_to_set_up_this_payment');

            return false;
        }

        if ($errors)
        {
            return false;
        }

        return true;
    }

    public function initiatePayment(Controller $controller, PurchaseRequest $purchaseRequest, Purchase $purchase)
    {
        $paymentProfile = $purchase->paymentProfile;
       
        $orderId = substr(hash('sha256', mt_rand() . microtime()), 0, 20);
       
        $signhash = ($paymentProfile->options['key'] . '|' . $orderId . '|' . $purchase->cost . '|' . $purchase->title . '|' . $purchase->purchaser->username . '|' . $purchase->purchaser->email . '|' . $purchase->purchasableId . '|' . $purchase->purchaser->user_id . '|||||||||' . $paymentProfile->options['salt']);
       
        $signature = strtolower(hash('sha512', $signhash));
       
        $costin = sprintf("%.1f",$purchase->cost);
       
        $params = [
           
            'key'                       =>  $paymentProfile->options['key'],
            'txnid'                     =>  $orderId,
            'amount'                    =>  $costin,
            'productinfo'               =>  $purchase->title,
            'firstname'                 =>  $purchase->purchaser->username,
            'email'                        =>    $purchase->purchaser->email,
            'phone'                        =>    $purchase->purchaser->Profile->custom_fields->phone,
            'surl'                        =>    $purchase->returnUrl,
            'furl'                      =>    $purchase->cancelUrl,
            'hash'                        =>    $signature,
            'service_provider'          =>  $paymentProfile->options['provider'],
            'udf1'                      =>    $purchase->purchasableId,
            'udf2'                         =>    $purchase->purchaser->user_id
           
           
           
        ];
       
       

        $viewParams = [
            'endpointUrl'        =>    $this->getApiEndpoint(),
            'purchaseRequest'    =>    $purchaseRequest,
            'paymentProfile'    =>    $paymentProfile,
            'purchasableTypeId'    =>    $purchase->purchasableTypeId,
            'purchasableId'        =>    $purchase->purchasableId,
            'purchase'            =>    $purchase,
            'params'            =>    $params
        ];

        return $controller->view('XXX\XXXXXXXXXXXXXX:Purchase\PayUInitiate', 'payu_payment_initiate', $viewParams);
    }

    public function setupCallback(Request $request)
    {
        $state = new CallbackState();

        $state->$status = $request->filter('status', 'str');
        $state->$firstname = $request->filter('firstname', 'str');
        $state->$amount = $request->filter('amount', 'str');
        $state->$txnid = $request->filter('txnid', 'str');
        $state->$hash = $request->filter('hash', 'str');
        $state->$key = $request->filter('key', 'str');
        $state->$productInfo  = $request->filter('productinfo', 'str');
        $state->$email = $request->filter('email', 'str');
        $state->$salt = $request->filter('salt', 'str');
        $state->$udf1 = $request->filter('udf1', 'str');
        $state->$udf2 = $request->filter('udf2', 'str');
        $state->$mihpayid = $request->filter('mihpayid', 'str');
        $state->$additionalCharges = $request->filter('additionalCharges', 'str');
       
        $state->_POST = $_POST;

        return $state;
    }

    public function validateCallback(CallbackState $state)
    {
        $purchaseRequest = $state->getPurchaseRequest();

               
        if ($state->hash == $this->getInSignature($state))    {
            $state->status = 'success';

            return true;
           
        } else     {
            $state->logType = 'error';
            $state->logMessage = 'Transaction Failed due to Hash MisMatch';

            return false;
        }
    }

    public function validateTransaction(CallbackState $state)
    {
        if (!$state->mihpayid || !$state->firstname)
        {
            $state->logType = 'info';
            $state->logMessage = 'No transaction or subscriber id';

            return false;
        }

        return parent::validateTransaction($state);
    }  

   
   
    public function getPaymentResult(CallbackState $state)
    {
        if ($state->status == 'success') {
            $state->paymentResult = CallbackState::PAYMENT_RECEIVED;
        } else {
            $state->paymentResult = CallbackState::PAYMENT_REVERSED;
        }
    }

    public function prepareLogData(CallbackState $state)
    {
        $state->_POST['mihpayid'] = $state->mihpayid;
        $state->logDetails = $state->_POST;
    }

    protected $supportedCurrencies = [
        'INR'
    ];

    public function verifyCurrency(PaymentProfile $paymentProfile, $currencyCode)
    {
        return (in_array($currencyCode, $this->supportedCurrencies));
    }  

   

    protected function getInSignature(CallbackState $state)
    {
        $paymentProfile = $state->getPaymentProfile();
        $getSign = $paymentProfile->options['key'];
        $getSalt = $paymentProfile->options['salt'];
   
   
      if ($state->additionalCharges == 'additionalCharges')
      {
   
        $hashRequest =
            $state->additionalCharges.'|'.
            $getSalt.'|'.
            $state->status.'||||||||||'.
            $state->udf2.'|'.
            $state->udf1.'|'.
            $state->email.'|'.
            $state->firstname.'|'.
            $state->productInfo.'|'.
            $state->amount.'|'.
            $state->txnid.'|'.
            $getSign
        ;

        $signature = strtolower(hash("sha512", $hashRequest));

        return $signature;
       }
   
    else {
       
        $hashRequest =
           
            $getSalt.'|'.
            $state->status.'||||||||||'.
            $state->udf2.'|'.
            $state->udf1.'|'.
            $state->email.'|'.
            $state->firstname.'|'.
            $state->productInfo.'|'.
            $state->amount.'|'.
            $state->txnid.'|'.
            $getSign
        ;

        $signature = strtolower(hash("sha512", $hashRequest));

        return $signature;
    }
    }
}

It would be great help if someone could figureout why it is failing to do checksum

below is the screen shot of error

checksum failed.webp
 
after some changes it started working and does successful payment.

i can see payments in payu merchant dashboard.

after payment it redirects to xf and states

Code:
Thank you for purchasing this upgrade.

When the payment has been approved, your account will be upgraded.

But when i look at payment provider log, nothing is logged in it and also users are not upgraded automatically to said group.

I am using following to log the data.
PHP:
public function prepareLogData(CallbackState $state)
    {
        
        $state->logDetails = $state->_POST;
    }

is there something i am missing in complete process.
 
Ok i manage to succeed

in payment log array it contain array with styling tags
HTML:
<pre class='xdebug-var-dump' dir='ltr'>
<small>C:\xampp\htdocs\dd\src\XF\Debugger.php:28:</small>
<b>array</b> <i>(size=53)</i>
  'mihpayid' <font color='#888a85'>=&gt;</font> <small>string</small> <font color='#cc0000'>'129213'</font> <i>(length=6)</i>
  'mode' <font color='#888a85'>=&gt;</font> <small>string</small> <font color='#cc0000'>'CC'</font> <i>(length=2)</i>

how to make it simple just Name and Value

i am using for logging

PHP:
$state->logDetails = $state->_POST;


after completion of payment on callback url i receive message
Code:
Payment received, upgraded/extended.

it wont redirect to upgrade PHP for showing status.

anybody can guide me on what i should do
 
Top Bottom