### Install Payment and Currency

Or using Drush : drush dl payment currency

Don’t forget to enable your new modules Payment and Currency. Note that Payment has several submodules, I don’t need them for this example.

Payment only gives the workflow. Payment comes with several Payment methods available, that are implementing Payment API to hook into the workflow. The topic is integrting Payment, not writting a payment method, so you can choose whatever method(s) you want from the Payment project page.

In this example, I will use Paypal. So if you are still with me, download paypal_payment :

PayPal Payment has several submodules, enable all available PayPal Payment submodules.

### Create a module to set up the form

Inside the module, let’s make the form. Two solutions: either use the standalone form provided by the module to make a simple payment, or integrate the payment to your own existing form.

#### Using the standalone form

Using the standalone form is pretty straightforward, make a form builder callback function like this:

### The “thank you for your purchase” page

The return page after the payment is handled by the function you specified while creating the Payment object.

If the user correctly gets back to the website (keep in mind it’s not always the case), you have access to the context data you passed to the Payment object, along with the Payment method return codes (given by the payment provider). You can use it to build your “thank you” page :

function _mycheckoutmodule_payment_complete($payment) { watchdog('mycheckoutmodule', '"Thank you" displayed for payment ' .$payment->pid . '.', array(), WATCHDOG_INFO); // Let's spam the logs        if ($payment->statuses[count($payment->statuses)-1]->status == 'payment_status_success') { // Actually pretty bad, but statuses stacks in the stored Payment object                drupal_set_message('Your payment has been received.', 'success');                drupal_goto('node/' . $payment->context_data['nid']); } else { drupal_set_message('Your payment is not yet validated, please wait.', 'warning'); drupal_goto('node/' .$payment->context_data['nid']);        }}

### Check if the Payment succeeded

#### IPN URL (for Paypal)

If you are using the Paypal payment method, you have to set up your Paypal account with the following URL : http://yoursite.com/paypal_payment_pps/return

#### The callback function

The IPN processing is abstracted by Payment module. Payment can provide you informations about current payment by using the Payment objects stored in Drupal’s database. So, process the payment when receiving the callback :

function _mycheckoutmodule_payment_status_changed($payment) { watchdog('mycheckoutmodule', 'Status for payment ' .$payment->pid . ' changed.', array(), WATCHDOG_INFO); // Let's spam the logs        if ($payment->statuses[count($payment->statuses)-1]->status == 'payment_status_success') {                watchdog('mycheckoutmodule', 'Status for payment ' . $payment->pid . ' detected completed.', array(), WATCHDOG_INFO); // spam, spam! _mycheckoutmodule_process_delivery($payment->context_data['nid']); // You should implement this to do something once the payment is received        };}

You can have a list of the available statuses in the file sites/all/modules/contrib/payment/payment/payment.payment.inc

#### The callback Rule

I didn’t find how to get the callback function triggering using an hook to Payment API. But Payment provides Rules conditions to handle the callbacks, let’s use it.

You can programmatically add a rule to your module, but if you are a lazy man like me, just add it from Rules UI : define a condition “payment status changed” and action “execute PHP” to call your function :

_mycheckoutmodule_payment_status_changed(\$payment);

### Known bugs

There are some cutting edge while using this module : I didn’t succeeded at having the price rounded while using the “tax” argument. As a walkaround, you can just skip the “tax” argument of the form, or set it to 0. You need a simple form, so you maybe you don’t bother about dislaying the tax rate or not.