Skip to content

Commit

Permalink
controller to handle stripe checkout and authorization
Browse files Browse the repository at this point in the history
  • Loading branch information
saurabh6790 committed Mar 30, 2017
1 parent e9fbed7 commit 02fe610
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 23 deletions.
107 changes: 106 additions & 1 deletion frappe/integrations/doctype/stripe_settings/stripe_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,111 @@
from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
from frappe import _
import urllib
from frappe.utils import get_url, call_hook_method, cint
from frappe.integrations.utils import make_get_request, make_post_request, create_request_log, create_payment_gateway

class StripeSettings(Document):
pass
supported_currencies = [
"AED", "ALL", "ANG", "ARS", "AUD", "AWG", "BBD", "BDT", "BIF", "BMD", "BND",
"BOB", "BRL", "BSD", "BWP", "BZD", "CAD", "CHF", "CLP", "CNY", "COP", "CRC", "CVE", "CZK", "DJF",
"DKK", "DOP", "DZD", "EGP", "ETB", "EUR", "FJD", "FKP", "GBP", "GIP", "GMD", "GNF", "GTQ", "GYD",
"HKD", "HNL", "HRK", "HTG", "HUF", "IDR", "ILS", "INR", "ISK", "JMD", "JPY", "KES", "KHR", "KMF",
"KRW", "KYD", "KZT", "LAK", "LBP", "LKR", "LRD", "MAD", "MDL", "MNT", "MOP", "MRO", "MUR", "MVR",
"MWK", "MXN", "MYR", "NAD", "NGN", "NIO", "NOK", "NPR", "NZD", "PAB", "PEN", "PGK", "PHP", "PKR",
"PLN", "PYG", "QAR", "RUB", "SAR", "SBD", "SCR", "SEK", "SGD", "SHP", "SLL", "SOS", "STD", "SVC",
"SZL", "THB", "TOP", "TTD", "TWD", "TZS", "UAH", "UGX", "USD", "UYU", "UZS", "VND", "VUV", "WST",
"XAF", "XOF", "XPF", "YER", "ZAR"
]

def validate(self):
create_payment_gateway('Stripe')
call_hook_method('payment_gateway_enabled', gateway='Stripe')
if not self.flags.ignore_mandatory:
self.validate_stripe_credentails()

def validate_stripe_credentails(self):
if self.publishable_key and self.secret_key:
header = {"Authorization": "Bearer {0}".format(self.get_password(fieldname="secret_key", raise_exception=False))}
try:
make_get_request(url="https://api.stripe.com/v1/charges", headers=header)
except Exception:
frappe.throw(_("Seems Publishable Key or Secret Key is wrong !!!"))

def validate_transaction_currency(self, currency):
if currency not in self.supported_currencies:
frappe.throw(_("Please select another payment method. Stripe does not support transactions in currency '{0}'").format(currency))

def get_payment_url(self, **kwargs):
return get_url("./integrations/stripe_checkout?{0}".format(urllib.urlencode(kwargs)))

def create_request(self, data):
self.data = frappe._dict(data)

try:
self.integration_request = create_request_log(self.data, "Host", "Stripe")
return self.create_charge_on_stripe()
except Exception:
frappe.log_error(frappe.get_traceback())
return{
"redirect_to": frappe.redirect_to_message(_('Server Error'), _("Seems issue with server's razorpay config. Don't worry, in case of failure amount will get refunded to your account.")),
"status": 401
}

def create_charge_on_stripe(self):
headers = {"Authorization":
"Bearer {0}".format(self.get_password(fieldname="secret_key", raise_exception=False))}

data = {
"amount": cint(self.data.amount)*100,
"currency": self.data.currency,
"source": self.data.stripe_token_id,
"description": self.data.description
}

redirect_to = self.data.get('redirect_to') or None
redirect_message = self.data.get('redirect_message') or None

try:
resp = make_post_request(url="https://api.stripe.com/v1/charges", headers=headers, data=data)

if resp.get("captured") == True:
self.integration_request.db_set('status', 'Completed', update_modified=False)
self.flags.status_changed_to = "Completed"

else:
frappe.log_error(str(resp), 'Stripe Payment not completed')

except:
frappe.log_error(frappe.get_traceback())
# failed
pass

status = frappe.flags.integration_request.status_code

if self.flags.status_changed_to == "Completed":
if self.data.reference_doctype and self.data.reference_docname:
custom_redirect_to = None
try:
custom_redirect_to = frappe.get_doc(self.data.reference_doctype,
self.data.reference_docname).run_method("on_payment_authorized", self.flags.status_changed_to)
except Exception:
frappe.log_error(frappe.get_traceback())

if custom_redirect_to:
redirect_to = custom_redirect_to

redirect_url = 'payment-success'
else:
redirect_url = 'payment-failed'

if redirect_to:
redirect_url += '?' + urllib.urlencode({'redirect_to': redirect_to})
if redirect_message:
redirect_url += '&' + urllib.urlencode({'redirect_message': redirect_message})

return {
"redirect_to": redirect_url,
"status": status
}
21 changes: 13 additions & 8 deletions frappe/integrations/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,41 @@
from frappe.utils import get_request_session
from frappe import _

def make_get_request(url, auth=None, data=None):
def make_get_request(url, auth=None, headers=None, data=None):
if not auth:
auth = ''
if not data:
data = {}
if not headers:
headers = {}

try:
s = get_request_session()
frappe.flags.integration_request = s.get(url, data={}, auth=auth)
frappe.flags.integration_request = s.get(url, data={}, auth=auth, headers=headers)
frappe.flags.integration_request.raise_for_status()
return frappe.flags.integration_request.json()

except Exception, exc:
frappe.log_error(frappe.get_traceback())
raise exc

def make_post_request(url, auth=None, data=None):
def make_post_request(url, auth=None, headers=None, data=None):
if not auth:
auth = ''
if not data:
data = {}
if not headers:
headers = {}

try:
s = get_request_session()
res = s.post(url, data=data, auth=auth)
res.raise_for_status()
frappe.flags.integration_request = s.post(url, data=data, auth=auth, headers=headers)
frappe.flags.integration_request.raise_for_status()

if res.headers.get("content-type") == "text/plain; charset=utf-8":
return urlparse.parse_qs(res.text)
if frappe.flags.integration_request.headers.get("content-type") == "text/plain; charset=utf-8":
return urlparse.parse_qs(frappe.flags.integration_request.text)

return res.json()
return frappe.flags.integration_request.json()
except Exception, exc:
frappe.log_error()
raise exc
Expand Down
9 changes: 3 additions & 6 deletions frappe/templates/includes/integrations/stripe_checkout.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ $(document).ready(function(){
(function(e){
var handler = StripeCheckout.configure({
key: "{{ publishable_key }}",
image: 'https://stripe.com/img/documentation/checkout/marketplace.png',
locale: 'auto',
token: function(token) {
// You can access the token ID with `token.id`.
// Get the token ID to your server-side code for use.
stripe.make_payment_log(token, handler);
stripe.make_payment_log(token, {{ frappe.form_dict|json }}, "{{ reference_doctype }}", "{{ reference_docname }}");
}
});

Expand All @@ -24,17 +22,16 @@ $(document).ready(function(){

frappe.provide('stripe');

stripe.make_payment_log = function(token, handler, doctype, docname){
stripe.make_payment_log = function(token, data, doctype, docname){
$('.stripe-loading').addClass('hidden');
$('.stripe-confirming').removeClass('hidden');

frappe.call({
method:"frappe.templates.pages.integrations.stripe_checkout.make_payment",
freeze:true,
headers: {"X-Requested-With": "XMLHttpRequest"},
args: {
"stripe_token_id": token.id,
"options": handler,
"data": JSON.stringify(data),
"reference_doctype": doctype,
"reference_docname": docname
},
Expand Down
11 changes: 3 additions & 8 deletions frappe/templates/pages/integrations/stripe_checkout.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,11 @@ def get_api_key():
return publishable_key

@frappe.whitelist(allow_guest=True)
def make_payment(stripe_token_id, options=None, reference_doctype=None, reference_docname=None):
data = {}

if isinstance(options, basestring):
data = json.loads(options)
def make_payment(stripe_token_id, data, reference_doctype=None, reference_docname=None):
data = json.loads(data)

data.update({
"stripe_payment_id": stripe_token_id,
"reference_docname": reference_docname,
"reference_doctype": reference_doctype
"stripe_token_id": stripe_token_id
})

data = frappe.get_doc("Stripe Settings").create_request(data)
Expand Down

0 comments on commit 02fe610

Please sign in to comment.