[IMP] website_payment: generic payment controller

- generate payment from the frontend using a simple form
- send a payment with a simple url
- define a default provider for payments
This commit is contained in:
Damien Bouvy
2015-09-04 16:08:22 +02:00
parent f8a98d977e
commit f341ca62ab
8 changed files with 234 additions and 12 deletions
+1
View File
@@ -14,6 +14,7 @@
'data': [
'views/website_payment_view.xml',
'views/website_payment_templates.xml',
'views/res_config_view.xml',
],
'auto_install': False,
}
+60 -3
View File
@@ -1,9 +1,6 @@
# -*- coding: utf-8 -*-
import werkzeug
from openerp import http
from openerp.http import request
from openerp import tools
from openerp.tools.translate import _
@@ -27,3 +24,63 @@ class website_payment(http.Controller):
pay_meth = request.env['payment.method'].browse(int(delete_pm_id))
pay_meth.unlink()
return request.redirect('/my/payment_method')
@http.route(['/website_payment/pay'], type='http', auth='public', website=True)
def pay(self, reference='', amount=False, currency_id=None, acquirer_id=None, **kw):
env = request.env
user = env.user.sudo()
currency_id = currency_id and int(currency_id) or user.company_id.currency_id.id
currency = env['res.currency'].browse(currency_id)
# Try default one then fallback on first
acquirer_id = acquirer_id and int(acquirer_id) or \
env['ir.values'].get_default('payment.acquirer', 'acquirer_id') or \
env['payment.acquirer'].search([('website_published', '=', True)])[0].id
acquirer = env['payment.acquirer'].with_context(submit_class='btn btn-primary pull-right',
submit_txt=_('Pay Now')).browse(acquirer_id)
# auto-increment reference with a number suffix if the reference already exists
ref_suffix = 1
init_ref = reference
while request.env['payment.transaction'].sudo().search_count([('reference', '=', reference)]):
reference = init_ref + '-' + str(ref_suffix)
ref_suffix += 1
partner_id = user.partner_id.id if user.partner_id.id != request.website.partner_id.id else False
payment_form = acquirer.render(reference, float(amount), currency.id, values={'return_url': '/website_payment/confirm', 'partner_id': partner_id})[0]
values = {
'reference': reference,
'acquirer': acquirer,
'currency': currency,
'amount': amount,
'payment_form': payment_form,
}
return request.website.render('website_payment.pay', values)
@http.route(['/website_payment/transaction'], type='json', auth="public", website=True)
def transaction(self, reference, amount, currency_id, acquirer_id):
partner_id = request.env.user.partner_id.id if request.env.user.partner_id != request.website.partner_id else False
values = {
'acquirer_id': int(acquirer_id),
'reference': reference,
'amount': float(amount),
'currency_id': int(currency_id),
'partner_id': partner_id,
}
tx = request.env['payment.transaction'].sudo().create(values)
request.session['website_payment_tx_id'] = tx.id
return tx.id
@http.route(['/website_payment/confirm'], type='http', auth='public', website=True)
def confirm(self, **kw):
tx_id = request.session.pop('website_payment_tx_id', False)
if tx_id:
tx = request.env['payment.transaction'].browse(tx_id)
status = (tx.state == 'done' and 'success') or 'danger'
message = (tx.state == 'done' and 'Your payment was successful! It may take some time to be validated on our end.') or 'OOps! There was a problem with your payment.'
return request.website.render('website_payment.confirm', {'tx': tx, 'status': status, 'message': message})
else:
return request.redirect('/my/home')
+2 -1
View File
@@ -1,2 +1,3 @@
import website
import res_config
import payment
import website
@@ -0,0 +1,25 @@
from openerp import api, fields, models
class PaymentConfigSettings(models.TransientModel):
_inherit = 'account.config.settings'
default_acquirer = fields.Many2one("payment.acquirer",
string="Default Acquirer",
help="Default payment acquirer for website payments; your provider needs to be visible in the website.",
domain="[('website_published','=',True)]"
)
@api.model
def get_default_acquirer(self, fields):
default_acquirer = False
if 'default_acquirer' in fields:
default_acquirer = self.env['ir.values'].get_default('payment.transaction', 'acquirer_id', company_id=self.env.user.company_id.id)
return {
'default_acquirer': default_acquirer
}
@api.multi
def set_default_acquirer(self):
for wizard in self:
self.env['ir.values'].set_default('payment.transaction', 'acquirer_id', wizard.default_acquirer.id, company_id=self.env.user.company_id.id)
@@ -0,0 +1,38 @@
odoo.define('website_payment.website_payment', function (require) {
"use strict";
var website = require('website.website');
var ajax = require('web.ajax');
if(!$('.o_website_payment').length) {
return $.Deferred().reject("DOM doesn't contain '.o_website_payment'");
}
// When clicking on payment button: create the tx using json then continue to the acquirer
var $payment = $(".o_website_payment_form");
$payment.on("click", 'button[type="submit"],button[name="submit"]', function (ev) {
ev.preventDefault();
ev.stopPropagation();
$(ev.currentTarget).attr('disabled', true);
$(ev.currentTarget).prepend('<i class="fa fa-refresh fa-spin"></i> ');
var $form = $(ev.currentTarget).parents('form');
var data =$("div[class~='o_website_payment_new_payment']").data();
console.log(data);
ajax.jsonRpc('/website_payment/transaction/', 'call', data).then(function (result) {
$form.submit();
});
function getFormData($form){
var unindexed_array = $form.serializeArray();
var indexed_array = {};
$.map(unindexed_array, function(n, i){
indexed_array[n.name] = n.value;
});
return indexed_array;
}
});
});
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<data>
<record id="website_default_acquirer" model="ir.ui.view">
<field name="name">account.config.settings.inherit</field>
<field name="model">account.config.settings</field>
<field name="inherit_id" ref="payment.payment_acquirer_installation"/>
<field name="arch" type="xml">
<xpath expr="//div[@name='configure_payments_button']" position="after">
<div name="customer_payments">
<label for="default_acquirer"/>
<field name="default_acquirer" class="oe_inline"/>
</div>
</xpath>
</field>
</record>
</data>
</odoo>
@@ -2,7 +2,7 @@
<openerp>
<data>
<template id="header_footer_custom_payment" inherit_id="website.footer_default" customize_show="True" active="False" name="Payment Methods">
<xpath expr="//div[@id='info']" position="inside">
<xpath expr="//div[@class='o_my_details']" position="inside">
<h4 class="payment_method_title">Payment Method</h4>
<ul class="payment_method_list list-inline">
<t t-foreach="request.website.payment_acquirers()" t-as="acquirer">
@@ -18,13 +18,14 @@
<link rel='stylesheet' href='/website_payment/static/src/css/website_payment.css'/>
<script type="text/javascript" src="/website_payment/static/src/js/payment_acquirer.js"></script>
<script type="text/javascript" src="/website_payment/static/lib/jquery.payment/jquery.payment.js"></script>
<script type="text/javascript" src="/website_payment/static/src/js/payment_transaction.js"></script>
</xpath>
</template>
<template id="pay_methods" name="Payment Methods">
<t t-call="website.layout">
<t t-set="additional_title">Payment Methods</t>
<div id="wrap">
<div class="wrap">
<div class="container">
<div class="row">
<div class="col-sm-6">
@@ -82,5 +83,88 @@
</xpath>
</template>
<template id="pay">
<t t-call="website.layout">
<t t-set="additional_title">Payment</t>
<div class="wrap">
<div class="container o_website_payment">
<h1>Payment</h1>
<div class="row">
<div class="col-md-6">
<div class="oe_structure"></div>
<div>
<div class="form-horizontal row o_website_payment_new_payment" t-att-data-acquirer_id="acquirer.id" t-att-data-currency_id="currency.id" t-att-data-reference="reference" t-att-data-amount="amount">
<div class="form-group">
<label for="form_reference" class="col-sm-3 control-label">Reference</label>
<div class="col-sm-9">
<span name="form_reference" class="form-control" t-esc="reference"/>
</div>
</div>
<div class="form-group">
<label for="form_amount" class="col-sm-3 control-label">Amount</label>
<div class="col-sm-9">
<span name="form_amount" class="form-control" t-esc="amount"/>
<!--
<span name="form_amount" class="form-control" t-esc="amount" t-esc-options='{"widget": "monetary", "display_currency": "currency"}'/>
-->
</div>
</div>
<div class="col-sm-12 o_website_payment_form" t-raw="payment_form"/>
<div class="col-sm-6 col-sm-offset-6 text-muted mt16">
<img alt="payment_provider_logo" class="pull-right ml8" t-att-src="website.image_url(acquirer, 'image_small')"/>
<span>This transaction will be processed by <t t-esc="acquirer.name"/>.</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</t>
</template>
<template id="confirm">
<t t-call="website.layout">
<t t-set="additional_title">Payment</t>
<div class="wrap">
<div class="container o_website_payment">
<h1>Payment</h1>
<div class="row">
<div class="col-md-6">
<div class="form-horizontal">
<div t-attf-class="alert alert-#{status}" t-esc="message"/>
<div class="form-group">
<label for="form_partner_name" class="col-sm-3 control-label">From</label>
<div class="col-sm-9">
<span name="form_partner_name" class="form-control" t-esc="tx.partner_name"/>
</div>
</div>
<div class="form-group">
<label for="form_reference" class="col-sm-3 control-label">Reference</label>
<div class="col-sm-9">
<span name="form_reference" class="form-control" t-esc="tx.reference"/>
</div>
</div>
<div class="form-group">
<label for="form_amount" class="col-sm-3 control-label">Amount</label>
<div class="col-sm-9">
<span name="form_amount" class="form-control" t-esc="tx.amount" t-esc-options='{"widget": "monetary", "display_currency": "tx.currency_id"}'/>
</div>
</div>
<div class="col-sm-12">
<a t-attf-class="btn btn-#{status} pull-right" href="/my/home"><i class="fa fa-arrow-circle-right"/> Back to My Account</a>
</div>
<div class="col-sm-6 col-sm-offset-6 text-muted mt16">
<img alt="payment_provider_logo" class="pull-right ml8" t-att-src="website.image_url(tx.acquirer_id, 'image_small')"/>
<span>Payment processed by <t t-esc="tx.acquirer_id.name"/>.</span>
</div>
</div>
</div>
</div>
</div>
</div>
</t>
</template>
</data>
</openerp>
@@ -24,12 +24,10 @@
<field name="model">payment.acquirer</field>
<field name="inherit_id" ref="payment.acquirer_form"/>
<field name="arch" type="xml">
<xpath expr="//group[@name='acquirer_base']" position="before">
<div class="oe_button_box" name="button_box">
<button class="oe_stat_button" name="website_publish_button" type="object" icon="fa-globe">
<field name="website_published" widget="website_button"/>
</button>
</div>
<xpath expr="//div[@class='oe_button_box']/*[1]" position="before">
<button class="oe_stat_button" name="website_publish_button" type="object" icon="fa-globe">
<field name="website_published" widget="website_button"/>
</button>
</xpath>
</field>
</record>