Online Payment Module Architecture
Introduction
This page describe how the modules for online payments works.
This is how the Module Stripe, the Module PayPal but also external modules like the Module HelloAsso are working. For core module, the code is hard coded, for external modules code is executed at the same place than core modules, but it is triggered by hooks instead of being hard coded.
Step 1 - The choice of the payment mode
First step to make an online payment is done by calling the public page /public/payment/newpayment.php
This page is common to all payment mode. It page accepts some parameters to know how to find the amount. This is a list of all possible URLs:
- URL to offer an online payment page of any amount with no existing object:
https://demo.dolibarr.org/public/payment/newpayment.php?amount=9.99&tag=your_tag
- URL to offer an online payment page for a sales order:
https://demo.dolibarr.org/public/payment/newpayment.php?source=order&ref=order_ref
- URL to offer an online payment page for a customer invoice:
https://demo.dolibarr.org/public/payment/newpayment.php?source=invoice&ref=invoice_ref
- URL to offer a Stripe online payment page for a contract line:
https://demo.dolibarr.org/public/payment/newpayment.php?source=contractline&ref=contractline_ref
- URL to offer a Stripe online payment page for a member subscription:
https://demo.dolibarr.org/public/payment/newpayment.php?source=membersubscription&ref=member_ref
- URL to offer a Stripe online payment page for payment of a donation:
https://demo.dolibarr.org/public/payment/newpayment.php?source=donation&ref=donation_ref
The parameter are used by the page to find the amount to ask for the payment from the object retrieved in URL.
Then the page search the list of all available payment mode by calling getValidOnlinePaymentMethods(). To complete this list to add your own module, you must implement the hook getValidPayment of the context nexpayment.
$hookmanager->resarray = array('mypaymentcode => 'valid');
Then for each entry found the page suggest the payment mode as a different button "Pay using MyPaymentMode". To output HTML code of your button, you must use the hook doAddButton for the context "newpayment". Your hook must return an
$this->resarray = array('mypaymentcode' => 'MyPaymentMode Label on Button')
If you want you can also implement the hook checkStatus to retrieve information from your payment platform to show information on the payment page.
=> Once done, you can already test your module integration by checking that a new entry to pay appear on the payment page.
Step 2 - User choose the payment mode
When the user has clicked on a payment mode, the same page is called but with a parameter action=dopayment.
If the payment mode needs to, some information about the payment are stored into session so it will be possible to retrieve them later when falling back on the result of payment page.
Among information automatically saved into session, you ha:ve
- the amount into $_SESSION['FinalPaymentAmount']
- currency code
- ip address of user
You can complete with any variable of your choice. A lot of information about the payment are available into variable $FULLTAG that contains information on the source of the payment (the mode but also the object of Dolibarr the payment may be related to). Content of the $FULLTAG string must be provided to the payment system because it is required to have it returned in the fallback URL called once a payment has been done (see STEP 4)
Depending on the payment mode, the page may prepare the payment on the remote system. It may be an API call or a redirect to another page. Then the page should:
- show the form to allow the user payment page embedded into the dolibarr newpayment page (example with Stripe payment mode).
- or the page may also choose to make a redirect to another page (on remote system) that ask this information (example with Paypal payment mode).
For all of this, you must implement the hook doPayment in the context 'newpayment'.
If you need to embed you own form, the content must returned by the hook, for example:
this->resPrint = '<script>my javascript</script><form><input type="text" name="credit card num"></form>';
If you need to make a redirect to an external page, do it into this hook with:
header("Location: myexternalpaymenturl?keyforfulltag=$FULLTAG&myotherparameters");
exit;
Do not return value, just do an exit after the redirect.
=> You can now test that after the click on your payment mode, the redirect to you home page is ok or the form is shown.
Step 3 - Entering payment information
When the form to enter payment information are submitted (whatever is the page that handle it), the payment system should send a redirect to the page /public/payment/paymentok.php or public/payment/paymentko.php depending on status of payment.
- If the page to enter the payment was an external page, this external page must do a redirect to the one or the other (depending on success or not) but in both cases, the content of the variable $FULLTAG must be provided inside a parameter fulltag.
- If the page to enter payment was the newpayment page, using the a custom form, you can retrieve the submit of the form inside the hook doAction. You must use a parameter submited by your form to make the difference between the use of the hook in this step, after a payment has been done, or the use of the hook at the previous step (when the page is shown to output the form to enter payment information).
Step 4 - Fallback on result page
When payment is complete, the use finally reach the page paymentok.php or paymentko.php. The page paymentko will just return a message to explain the payment has failed. The page paymentok, will use the parameter fulltag and variables saved into session to make complementary actions like (registering the payment in the application, closing the invoice, sending an email...). The paymentok/ko page can retrieve information from:
- Parameter "fulltag" AG (this parameter was defined into the public/payment/newpayment.php page). With this parameter, the page paymentok.php will be able to make all complementary action like closing invoice or order or recording a subscription for a membership subscription, and more...
- Some payment mode include also more parameters like PAYERID for Paypal. Only FULLTAG should be mandatory.
Some other parameters may be retrieved in the session like:
- $_SESSION['ipaddress']
- $_SESSION['errormessage'] An error message to show
Other features
To complete...