-
Notifications
You must be signed in to change notification settings - Fork 8
Integration Guide: Payments for Marketplace
Đào Hoàng Sơn edited this page Dec 23, 2015
·
2 revisions
This guide includes code to integrate [bd] Paygates as payment methods for your Marketplace add-on or similar.
To integrate payment methods, an add-on needs to do two things: rendering the payment forms (PayPal, Stripe, etc.) on a product page and handling callbacks (success, failure, etc.).
/* @var $processorModel bdPaygate_Model_Processor */
$processorModel
= $this->getModelFromCache('bdPaygate_Model_Processor');
// get all available payment processors
$processorNames = $processorModel->getProcessorNames();
$processors = array();
foreach ($processorNames as $processorId => $processorClass) {
$processors[$processorId]
= bdPaygate_Processor_Abstract::create($processorClass);
}
$visitor = XenForo_Visitor::getInstance();
// generate paygate-compatible item id
// $data is an array and it may any number of elements
// normally, you need to put in at least one internal id
// that can be used to know which product has been purchased
$data = array($product['product_id']);
$itemId = $processorModel->generateItemId('unique_action_code', $visitor, $data);
// change these variables if you do recurring payments
// $recurringUnit can be 'day', 'month' or 'year'
$recurringInterval = false;
$recurringUnit = false;
// the forms support some extra options you can make use of
$extraData = array();
// the most popular one is a return url after finishing the payment flow
// please note that user will be redirected there regardless of the transaction result
// because some processor takes time to verify their transaction
// so its result is not always immediately available
$extraData[bdPaygate_Processor_Abstract::EXTRA_RETURN_URL]
= XenForo_Link::buildPublicLink('full:products/buy/thank-you', $product);
$paymentForms = bdPaygate_Processor_Abstract::prepareForms($processors,
$product['amount'], $product['currency'],
$product['product_name'], $itemId,
$recurringInterval, $recurringUnit,
$extraData
);
You need to extends bdPaygate_Model_Processor
using XenForo code event listener and put something like below in it:
class AddOn_bdPaygate_Model_Processor extends XFCP_AddOn_bdPaygate_Model_Processor
{
protected function _processIntegratedAction(
$action, $user, $data,
bdPaygate_Processor_Abstract $processor, $amount, $currency)
{
switch ($action) {
case 'unique_action_code':
// $data is exactly the same as you created above
$productId = reset($data);
$productModel = $this->getModelFromCache('AddOn_Model_Product');
$product = $productModel->getProductById($productId);
// return immediately if your code encounters any errors
// the system will log everything for analysis later
if (!$product) return sprintf('Product #%s not found', $productId);
// some processors (but not all) report transferred amount, currency
// you can use that information to optionally verify
// whether user have purchased your product at the correct price
// be careful if your marketplace offers discount, coupons etc.
if ($amount !== false && $currency !== false) {
if ($amount - $product['amount'] > 0.001
|| utf8_strtolower($currency) !== $product['currency']
) {
return sprintf('Invalid purchase price of product #%d: %f %s (expected %f %s)',
$product['product_id'], $ammount, $currency,
$product['amount'], $product['currency']);
}
}
// if everything is good, update your product
// $user is the full record of the purchaser
$productModel->transferToUser($user);
return sprintf('User #%d (%s) has bought product #%d (%s)',
$user['user_id'], $user['username'],
$product['product_id'], $product['product_name']);
}
// make sure you call the parent method to avoid future conflicts
return parent::_processIntegratedAction($action, $user, $data, $processor, $amount, $currency);
}
}