2

I'm trying to get some custom value passed through paypal during a payment, so that paypal will give it back to me when the IPSN endpoint is called.

I do that with a regular html form and everything is fine, but if I do that with CI-Merchant the custom value is empty.

    $params = array(
        'amount' => $amount_dollars,
        'currency' => 'CAD',
        'description' => $paypal_description,
        'custom' => 'some_id='.$some_id_value,
        'return_url' => base_url('callback'),
        'cancel_url' => base_url('callback-cancelled'));

    $response = $this->merchant->purchase($params);

Does anybody know how can I get this to work?

Thanks Ivan

Ivan Carosati
  • 355
  • 4
  • 13

1 Answers1

6

CI Merchant allows you to stop worrying about handling the IPN yourself, so I think you're running into issues because you are trying to do too much work :)

The general process for processing a PayPal payment is outlined here: http://ci-merchant.org/

First, as you are doing, you would make a record of the payment in your database. This is usually separate to your orders table, so create a transactions table or something. Give the transaction a status of in_progress or something (in your database, the specifics are up to you).

Then, create the payment request as you are doing (make sure you are using paypal_express driver, not the old deprecated paypal driver):

$this->load->library('merchant');
$this->merchant->load('paypal_express');

$params = array(
    'amount' => $amount_dollars,
    'currency' => 'CAD',
    'description' => $paypal_description,
    'return_url' => base_url('callback'),
    'cancel_url' => base_url('callback-cancelled'));

$response = $this->merchant->purchase($params);

At this point, double check the response for failure. If it was successful, the user should already have been redirected to Paypal.

For what you are trying to do (identify the transaction in your notification URL), the trick is to use a custom return_url. For example:

'return_url' => base_url('callback/transaction/'.$transaction_id),

This means that on that page you can get the transaction ID from the segment variable. Your callback controller would look like this:

// which transaction did we just complete
$transaction_id = $this->uri->segment(3);

// query database to find out transaction details
$transaction = $this->db->where('transaction_id', $transaction_id)->get('transactions')->row();

// confirm the paypal payment
$this->load->library('merchant');
$this->merchant->load('paypal_express');

// params array should be identical to what you passed to the `purchase()` method
// normally you would have some shared method somewhere to generate the $params
$params = array(
    'amount' => $transaction->amount_dollars,
    'currency' => 'CAD',
    'description' => $transaction->description);

$response = $this->merchant->purchase_return($params);

At this point you can inspect the $response to check whether payment was successful, and update your database/act accordingly.

Adrian Macneil
  • 13,017
  • 5
  • 57
  • 70
  • Thanks, I really appreciate the time and the effort you put into this. I could do that, but in my specific case I need to perform heavy computation in the backend. I do check already the status of the callback to output the feedback for the user. I could call the backend after the callback but I was trying to get a nicer solution. – Ivan Carosati Feb 01 '13 at 02:28
  • What sort of computation? Whatever it is, you should probably just store it in your database along with the transaction ID, rather than relying on PayPal to pass it back to you (which might not work if you ever need to change payment gateways, which is one of the advantages of CI merchant) – Adrian Macneil Feb 01 '13 at 04:45
  • I ended up using you solution! Thanks. I store the transaction id with the callback URL, and the I use the IPNS for the computation in the backend. Is working really good! – Ivan Carosati Feb 02 '13 at 01:33