diff --git a/src/api/store.py b/src/api/store.py index cf42313..c1144e2 100644 --- a/src/api/store.py +++ b/src/api/store.py @@ -9,7 +9,7 @@ from utils.params import PARAMS as SYS_ARGS from utils import void import json class User : - def __init__(self,email,plans): + def __init__(self,email,plans=None): self.plans = plans self.me = {"plan":[],"customer":{},"payments":[],"plan2sub":{}} self.init(email) @@ -17,41 +17,94 @@ class User : pass def info(self): return self.me['customer'] - def _add_card(self,card): + def _add_card(self,**_args): + """ + creating a card token, we do not have to save this it could just be used as a one-time thing, + This will automatically add a card to the users session profile (if she has not specified to save the card) + :number + :cvc + :exp mm/yyyy + + """ try: - stripe.token.Token.create(customer=self.me["customer"]['id'],card=card) + card = dict(_args['card'] ) + for field in ['name','email'] : + + if field in card : + del card[field] + + # + # address information should be added to the card + # + # save_card = _args['save'] if 'save' in _args else 0 + # if save_card : + # r = stripe.token.Token.create(card=card) + # else: + # + # Links the customer to the source .. + if 'currency' in card : + currency = card['currency'] + del card['currency'] + else: + currency = 'usd' + r = stripe.source.Source.create(type='card',currency=currency,card=card) + self.me['payments'] = [r.card.to_dict_recursive()]+self.me['payments'] self.init(self.me["customer"]['email']) - return 1 + return r except Exception as error : print (error) - return 0 + return 0 + def charge(self,**args) : """ This function will charge a user for a service (given a plan id) - :plan_id plan identifier for the current product - :card_index provide a token (otherwise will use a valid card) + :card|token {number,cvc,exp_month,exp_year,[address_1,city,zip,state]} + :amount + :email + : """ - plan_id = args['plan_id'] - if len(self.me["payments"]) == 1 : - card_index = 0 - else: - card_index = args['card_index'] - plan = [item[plan_id] for item in self.plans if item['id'] == plan_id] + # plan_id = args['plan_id'] + # if len(self.me["payments"]) == 1 : + # card_index = 0 + # else: + # card_index = args['card_index'] + # plan = [item[plan_id] for item in self.plans if item['id'] == plan_id] + + # card = {} if plan['amount'] == 0 else self.me["payments"][card_index] + # params = {} - card = {} if plan['amount'] == 0 else self.me["payments"][card_index] - params = {} + # params['customer'] = self.me["customer"]['id'] + # params ['amount'] = plan['amount'] + # params ['currency'] = plan['currency'] + # params ['description'] = " ".join([self.product['statement_descriptor'],plan['nickname']]) + # if 'source' in card : + # params ['source'] = card['source'] - params['customer'] = self.me["customer"]['id'] - params ['amount'] = plan['amount'] - params ['currency'] = plan['currency'] - params ['description'] = " ".join([self.product['statement_descriptor'],plan['nickname']]) - if 'source' in card : - params ['source'] = card['source'] + # + # Lets create a token for the card + # - stripe.charge.Charge.create(params) - del params['amount'], params['currency'] + token = self.card.add(card = args['card']) + if token != 0 : + _args = {"customer":self.me["customer"]["id"], "receipt_email":self.me['customer']['email'],"amount":args['amount'],"currency":"usd"} + _args["source"] = token["id"] + if 'metadata' in args : + _args['metadata'] = args['metadata'] + # stripe.customer.Customer.update(self.me['customer']['id'],source=token['id']) + _args['description'] = args['description'] + stripe.charge.Charge.create(**_args) + # if 'save' not in args : + # # + # # drop the card ... + # stripe.customer.Customer.delete_source(self.me['customer']['id'],token['id']) + # del params['amount'], params['currency'] - stripe.invoice.Invoice.create(**params) + # stripe.invoice.Invoice.create(**params) + return 1 + else: + # + # An invalid card number or cvc we returned + return 0 pass def format(self): @@ -228,13 +281,27 @@ class Plans(Store) : This function will retrieve plan information associated with the given product id """ Store.__init__(self,**args) - self.plans = stripe.plan.Plan.list(product=self.product['id']).to_dict_recursive()['data'] - for item in self.plans : - index = self.plans.index(item) - self.plans[index] = item.to_dict_recursive() - if 'features' in self.plans[index]['metadata'] : - self.plans[index]['metadata']['features'] = json.loads(self.plans[index]['metadata']['features']) - self.plans.sort(key=lambda item: item['amount']) + + info = stripe.price.Price.list(product=self.product['id']).data + self.plans = [] + self.checkout = [] + for item in info : + setattr(item,'amount',item.unit_amount) + _item = item.to_dict_recursive() + _item['amount'] = item['unit_amount'] + if item.recurring == None : + self.checkout.append(_item) + elif 'features' in item.metadata : + _item['metadata']['features'] = json.loads(item.metadata['features']) + self.plans.append(_item) + # index = self.plans.index(item) + # self.plans[index] = item.to_dict_recursive() + # if 'features' in self.plans[index]['metadata'] : + # self.plans[index]['metadata']['features'] = json.loads(self.plans[index]['metadata']['features']) + # elif self.plans + + self.plans.sort(key=lambda item: item['unit_amount']) + self.checkout.sort(key=lambda item:item['unit_amount']) if 'email' in args : self.user = User(args['email'],self.plans) else: @@ -243,8 +310,9 @@ class Plans(Store) : self.format() def format(self): self.get = void() - self.get.plans = lambda:self.plans - self.get.products = lambda:self.products + self.get.plans = lambda:self.plans + self.get.checkout = lambda: self.checkout + self.get.products = lambda:self.products self.plan = void() self.plan.upgrade = self.upgrade self.plan.cancel = self.cancel @@ -326,236 +394,4 @@ class factory: # p.user.subscribe = p.subscribe return p - # if 'email' in args : - # store = Plans(**args) - - # else: - # store = Plans(**args) - # return store -# class _Store : -# # stripe_keys = { -# # "secret_key":SYS_ARGS['stripe']['secret'].strip(), -# # "publishable_key":SYS_ARGS['stripe']['pub'].strip() -# # } -# # stripe.api_key = self.stripe_keys['secret_key'] - -# def __init__(saelf,**args): -# self.payment = [] -# self.user_plan = {} -# self.customer = {} - -# self.get = void() -# # self.get.user = void() -# # self.get.user.info = self._get_user -# # self.get.user.plan = lambda: self.user_plan if self.user_plan else None - - -# # self.add = void() -# # self.add.user = self.init -# # self.add.card = lambda card: stripe.token.Token.create(customer=customer['id'],card=card) - -# self.user = void() -# self.user.init = self.init -# self.user.info = self._get_user -# self.user.plan = void() -# self.user.plan.info = lambda: self.user_plan if self.user_plan else None -# # self.user.plan.cancel = lambda id: stripe.subscription.Subscription.delete(self.customer['id'],prorate=True,invoice_now=True) - -# self.user.card = void () -# self.user.card.exists = lambda: len(self.payment) > 0 -# self.user.card.add = self._add_card -# self.user.card.charge = self._apply_charge -# self.user.card.html = lambda: [{} for card in self.payment] -# self.user.card.delete = lambda index: stripe.customer.Customer.delete_source(self.customer['id'],self.payment[index]) - -# self.get.plans = self._get_plans - - -# self.has = void () - -# product_name = args['product'] -# stripe.api_key = args['secret'] if 'secret' in args else stripe.api_key -# if stripe.api_key : -# self.__init_product(product_name) -# else: -# print (['secret' in args, stripe.api_key is None]) -# self.plan = void() -# self.plan.cancel = self.__cancel_plan -# self.plan.subscribe = self.__subscribe_plan -# self.plan.upgrade = self.__upgrade_plan -# def _apply_charge(self,**args) : -# """ -# This function will charge a user for a service (given a plan id) -# :plan_id plan identifier for the current product -# :card_index provide a token (otherwise will use a valid card) -# """ -# plan_id = args['plan_id'] -# if len(self.payment) == 1 : -# card_index = 0 -# else: -# card_index = args['card_index'] -# plan = [item[plan_id] for item in self.plans if item['id'] == plan_id] - -# card = {} if plan['amount'] == 0 else self.payment[card_index] -# params = {} - -# params['customer'] = self.customer['id'] -# params ['amount'] = plan['amount'] -# params ['currency'] = plan['currency'] -# params ['description'] = " ".join([self.product['statement_descriptor'],plan['nickname']]) -# if 'source' in card : -# params ['source'] = card['source'] - -# stripe.charge.Charge.create(params) -# del params['amount'], params['currency'] - -# stripe.invoice.Invoice.create(**params ) -# pass -# def __init_product(self,product_name): -# PRODUCT_INDEX = 2 -# DATA_TYPE_INDEX = 1 -# STATUS_INDEX = 0 -# resp = stripe.product.Product.list().to_dict_recursive()['data'] -# self.product = [] -# self.plan = [] -# if resp : - -# if resp : -# self.product = [p.to_dict_recursive() for p in resp if p['name'] == product_name] -# self.product = self.product[0] if self.product else [] -# else: -# self.product = resp[0] - -# if 'id' in self.product : -# self.__init_plan(self.product['id']) - -# def __init_plan(self,id): -# """ -# This function will retrieve plan information associated with the given product id -# """ -# self.plans = stripe.plan.Plan.list(product=id).to_dict_recursive()['data'] -# for item in self.plans : -# index = self.plans.index(item) -# self.plans[index] = item.to_dict_recursive() -# if 'features' in self.plans[index]['metadata'] : -# self.plans[index]['metadata']['features'] = json.loads(self.plans[index]['metadata']['features']) -# # -# # sort items by amounts -# # -# self.plans.sort(key=lambda item: item['amount']) -# # self.plans = [item.to_dict_recursive() for item in self.plans] - -# def init(self,email): -# # -# # get customer information -# # email = args['email'] -# self.user_plan = [] -# self.customer = {} -# customers = stripe.customer.Customer.list(email=email).to_dict_recursive()['data'] -# if customers : -# customers = customers[0] -# else: -# # -# # The user doesn't exist, we must create the user (without payment initially) -# # We can probably assign the user to a free plan if available -# # -# customers = stripe.customer.Customer.Create(email=email) -# free_plan = [item for item in self.plans if item['amount'] == 0] -# if free_plan : -# free_plan = free_plan[0] -# self.plan.subscribe(free_plan['id'],email) -# self.customer = {"email":email,"id":customers['id']} -# # -# # extract payments available, -# if 'sources' in customers and 'data' in customers['sources'] : -# if customers['sources']['data'] : -# self.payment = [ card.to_dict_recursive() for card in customers['sources']['data'] ] -# # -# # user plans -# info = customers -# subscriptions = info['subscriptions']['data'] -# ids = [plan['id'] for plan in self.plans ] -# _found = None -# for sub in subscriptions : -# aplan = sub['plan'] - -# if set([aplan['id']]) & set(ids): -# _found = sub.to_dict_recursive() -# break - -# self.user_plan = _found if _found else None -# def _get_user(self,**args): -# """ -# This function will return a customer information and associated plan (hopefully) -# :email -# """ -# return self.customer - -# def __cancel_plan(self,id) : -# """ -# This function will cancel a subscription given a user's email/or a subscription for the given product/user -# We are assuming one subscription one plan, no complex billing is involved (not good for startups) -# :email,subscription -# """ -# stripe.subscription.Subscription.delete(id,prorate=True,invoice_now=True) -# pass -# def __upgrade_plan(self,id,email=None): -# """ -# A change of plan suggests cancelling the current plan and assigning a new one. -# If it's a paid plan, the calling code must insure the user has an active token -# """ -# email = self.customer['email'] if email is None else email -# sub_id = self.user.plan.info()['id'] -# try: -# self.plan.cancel(sub_id) -# self.plan.subscribe(id,email) -# # -# # We need to reload everything -# self.user.init(email) -# except Exception as error : -# print (error) ; -# return 0 -# return 1 - -# pass -# def __subscribe_plan(self,id,email): -# """ -# Subscribe a user to a given plan assuming the user has already been initialized -# The responsibility falls upon the calling code to perform the cancellatioin of the existing plan and perform an upgrade -# """ - -# plan = {"plan": id} -# amount = sum([item['amount'] for item in self.plans if item['id'] == 0]) - -# if 'email' in self.customer and email == self.customer['email'] : -# email = self.customer['email'] -# else: -# self.init(email) -# # -# # We must insure the user is one of our customers i.e perhaps -# if amount == 0 or self.payment : -# stripe.subscription.Subscription.create( -# customer=self.customer['id'], #if not email else email, -# items=[plan] -# ) -# return 1 -# else: -# return 0 - - -# def _add_card(self,card): -# try: -# stripe.token.Token.create(customer=customer['id'],card=card) -# self.user.init(self.customer['email']) -# return 1 -# except Exception as error : -# print (error) -# return 0 - -# def _get_plans(self,**args) : -# """ -# This function will provide an plan for a given user given an email or the list of plans -# :email user email -# """ -# return self.user_plan if 'email' in args else self.plans - + \ No newline at end of file diff --git a/src/api/templates/card.html b/src/api/templates/card.html index f977d49..507f64e 100644 --- a/src/api/templates/card.html +++ b/src/api/templates/card.html @@ -1,10 +1,364 @@ - - - -
-
- {% for i in range(12) %} - {% endfor %} + + + + + + + + + + + + + + +
+
+
+
{{product.name}}
+
+
+ +
+ +
+
+ {{product.metadata.about}} +
-
- \ No newline at end of file +
+ +
+ +
+
+ + +
+
+ + + +
+
+ + + +
+
+ +
+ +
+
+ +
+ +
+ + +
+
+
+
+ <_input type="text" placeholder="State" data-pattern="[A-Z]+" value="USA" onkeyup="checkout.validate(event)"/> +
+
+ <_input type="text" placeholder="Zip Code" data-pattern="[0-9]{5,}" onkeyup="checkout.validate(event)"/> +
+
+ + +
+
+ +
+ + + Pay Now
+
+
+ + + +
+
+

The Phi Technology + + - {{product.name}} © +

+
+
+ + +
diff --git a/src/api/templates/data.json b/src/api/templates/data.json new file mode 100644 index 0000000..56d5269 --- /dev/null +++ b/src/api/templates/data.json @@ -0,0 +1,2 @@ +{"email": "nyemba@gmail.com", "fname": "steve", "lname": "nyemba", "amount": 2500, "number": "5555555555554444", "exp": "02/2024", "cvc": "666"} + diff --git a/src/api/templates/dialog.html b/src/api/templates/dialog.html new file mode 100644 index 0000000..4fc4ddc --- /dev/null +++ b/src/api/templates/dialog.html @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + +
+
+
+
{{title}}
+ {% if type != 'PROGRESS' %} +
+ +
+ {% else %} +
+ {% endif %} +
+
+
+ +
+
{{message|safe}}
+
+
+
+
diff --git a/src/api/templates/plans.html b/src/api/templates/plans.html index 1f4efce..9b35247 100755 --- a/src/api/templates/plans.html +++ b/src/api/templates/plans.html @@ -34,11 +34,11 @@ jx.modal.show({html:html,id:'dialog'}) jx.dom.set.value('signup-plan',data.nickname) - if(data.amount == 0){ + if(data.unit_amount == 0){ var price = 'Free' }else{ - var price = parseFloat(data.amount / 100 ).toFixed(2) - price = ([price, data.interval]).join(' / ') + var price = parseFloat(data.unit_amount / 100 ).toFixed(2) + price = ([price, data.recurring.interval]).join(' / ') } jx.dom.set.value('plan-price',price) //jx.dom.set.focus('email') @@ -69,7 +69,7 @@ var key = ([protocol,'://',host,'/cloud-view/oauth']).join('') //jx.cloudview.init(host,protocol) - + jx.cloudview.init("{{session['cloud-view']|safe}}") jx.cloudview.oauth.init(id,key,function(p){ // @@ -82,7 +82,7 @@ httpclient.setHeader("Content-Type","application/json") httpclient.setData(JSON.stringify(info) ) httpclient.post('{{context|safe}}/store',function(x){}) - if (data.amount == 0){ + if (data.unit_amount == 0){ // // We should not be prompting the user but automatically logging her into her session // @@ -105,13 +105,13 @@ script.setAttribute('data-key', x['data-key'].trim()) script.setAttribute('data-email', p.user.uid) script.setAttribute('data-name', data.nickname) - script.setAttribute('data-amount', data.amount) + script.setAttribute('data-amount', data.unit_amount) script.setAttribute('data-description','{{description|safe}} ' + data.nickname) script.src = 'https://checkout.stripe.com/checkout.js' - script.setAttribute('data-amount',data.amount) + script.setAttribute('data-amount',data.unit_amount) script.setAttribute('data-image','https://s3.amazonaws.com/stripe-uploads/acct_15kiA1EUWsmgY81Amerchant-icon-1493912370912-logo-0.png') - script.setAttribute('data-label',(['Pay $',data.amount,data.interval]).join(' ')) + script.setAttribute('data-label',(['Pay $',data.unit_amount,data.interval]).join(' ')) script.className = 'stripe-button' form.appendChild(script) @@ -159,13 +159,13 @@ var pay_now = function(auth,plan){ script.setAttribute('data-key', x['data-key'].trim()) script.setAttribute('data-email', auth.user.uid) script.setAttribute('data-name', plan.nickname) - script.setAttribute('data-amount', plan.amount) + script.setAttribute('data-amount', plan.unit_amount) script.setAttribute('data-description','{{description|safe}} ' + plan.nickname) script.src = 'https://checkout.stripe.com/checkout.js' - script.setAttribute('data-amount',plan.amount) + script.setAttribute('data-amount',plan.unit_amount) script.setAttribute('data-image','https://s3.amazonaws.com/stripe-uploads/acct_15kiA1EUWsmgY81Amerchant-icon-1493912370912-logo-0.png') - script.setAttribute('data-label',(['Pay $',plan.amount,plan.interval]).join(' ')) + script.setAttribute('data-label',(['Pay $',plan.unit_amount,plan.recurring.interval]).join(' ')) script.className = 'stripe-button' form.appendChild(script) @@ -266,15 +266,15 @@ var redirect_now = function(auth,plan){ {% else %}
{% endif %} - {% if item.amount == 0%} + {% if item.unit_amount == 0%}
Free
{%else%}
- $ {{ item.amount/100 }} - / {{item.interval[:]}} + $ {{ item.unit_amount/100 }} + / {{item.recurring.interval[:]}}
{% endif %} @@ -301,15 +301,15 @@ var redirect_now = function(auth,plan){
Signup Now
- {% if item.amount == 0%} + {% if item.unit_amount == 0%}
Free
{%else%}
- $ {{ item.amount/100 }} - / {{item.interval[:]}} + $ {{ item.unit_amount/100 }} + / {{item.recurring.interval[:]}}
{% endif %} diff --git a/src/api/templates/subscribe.html b/src/api/templates/subscribe.html index 0f0fbfd..f1da5e6 100755 --- a/src/api/templates/subscribe.html +++ b/src/api/templates/subscribe.html @@ -264,7 +264,7 @@ data-name="{{item.nickname}}" data-description="{{alias }}" - data-label="Signup $ {{item.amount/100 }} / {{item.interval[:2]}}" + data-label="Signup $ {{item.amount/100 }} / {{item.recurring.interval[:2]}}" data-image="https://s3.amazonaws.com/stripe-uploads/acct_15kiA1EUWsmgY81Amerchant-icon-1493912370912-logo-0.png" data-locale="auto">