Generate coupons for python flask - python-3.x

I'm trying to generate voucher coupons for my flask application.
I need coupon that are not easily made, that can be read with the proper key and unique through time.
I already tried hashids with something like:
from hashids import Hashids
hash_id = Hashids(salt='Super salt', min_length=8)
hash_id.encrypt(30)
# 'voRDznrz'
The problem being that the key generated will always be the same.
I also tried itsdangerous for a smarter solution:
import itsdangerous
signer = itsdangerous.URLSafeTimedSerializer("Super salt")
coupon = signer.dumps("30 days free!")
signer.load(coupon, max_age=3600*24*30)
# IjMwIGRheXMgZnJlZSEi.Dl1JAQ.u_ilEm7nQ_8XIQt3nbwe31hyyRc
The solution is far better but I need to store already used coupon to forbid any re-use. Also the coupon is quite ugly and hard to type for our users.
Solution:
Okay so I was using Stripe to make my payment, and the answer is in their doc.
Using Stripe in python you can create coupon this way:
stripe.api_key = "Your secret api key"
coupon = stripe.Coupon.create(
duration='repeating',
duration_in_month=2,
percent_off=100,)
This mean that the coupon will give 2 free month to any subscription, I didn't find how to select a specific product to which the coupon can be applied though.
With the coupon object created you just take his id, this is your coupon code. To bind it to a subscription (and apply it) you do:
subscription = stripe.Subscription.retrieve("Subscription ID")
subscription.coupon = coupon.id
subscription.save()

Normaly coupons are not hash keys, are just some text like 30FREE and are stored in a table with a column that indicates if the coupon has been used (and a coupon exists if is in the table).
If you are not using an ORM right now, i recommend SQLAlchemy with Flask-SLQAlchemy, are very easy to setup and start.
Note: you can assign a coupon to a segment of users making a relationship between the coupons table and the users table, and then implement the logic of only a user inside that group can redeem the coupon or something like that.

Related

updating Stripe Price object

I had a question that seems to be easy but apparently is not working. I need to update the price for a Price object, but the following does not work. It gives the error that unit_amount is not known, although we use it to define the Price object initially:
stripe.Price.modify(
"price_1Hkb5FHdAaIdH7ntvOhZOyFK",
unit_amount=10,
)
You can not modify the price of a Price in the API. This is not something that is supported as there's no corresponding parameter on the API.
If you want to change the amount associated with a Price, you would create a new Price object and start using it instead. You could also make the old one inactive for example.
Another powerful feature of Stripe's API is the lookup_key on Price (doc). This lets you define a custom alias for your Price in your code. That way instead of hardcoding the price id price_123 in your code and having to update it to use price_abcd, you can transfer the old lookup key from the old price to the new one and have your code seamlessly start using the new one automatically. The idea is that you either cache the Price id associated with a lookup key based on webhooks for example or use the List Prices API and the lookup_keys parameter to quickly find the latest price id associated with a given lookup key!

Get Default Payment Source (default card) for Stripe Customer?

I created a POC with a customer/credit card in Stripe and I logged into my dashboard within Stripe and was able to see this customer has a default source (the test credit card I added) associated correctly. It shows this card is the default source.
When I run this .Net code:
var customerService = new CustomerService();
var stripeCustomer = await customerService.GetAsync(customerId);
To get that customer, it returns everything correctly except his source. All of the fields I had hoped I can find it from are empty! I want to know his default payment source so I can show it on the front end with a little icon to indicate it's default.
DefaultSource, DefaultSourceId, and Sources properties are all blank/null.
Is there a way to have Stripe return it, or do I need to do something else? I tried the 'expand' property for the GetAsync method but that threw an error saying the above properties are not expandable (i.e. I can't ask Stripe to expand/return Source).
Any ideas what I can do?
FYI I also tried this:
var paymentMethodService = new PaymentMethodService();
var cards = await paymentMethodService.ListAsync(new PaymentMethodListOptions { Customer = customerId, Type = "card"});
and there doesn't seem to be a property anywhere that says the card is default (although it does correctly return all cards). I believe Stripe documentation states the Customer is the holder of the default source, not the card object. What gives?
Thanks in advance!
It looks like you're using Payment Methods, since your payment method list call has the results you expect, which means the customer likely doesn't have any sources. You can try that again with the properly pluralized expand[]=sources if you do know your Customer has Sources attached.
For Payment Methods, there is no general default for the Customer. For one-time Payment Intents, you must always specify the payment_method from among those attached to the Customer for future payments.
For paying invoices (related to recurring subscriptions, eg), you can set the invoice_settings.default_payment_method for Customer. This only applies to invoices.

How to retrieve a Stripe Promo code by code

It looks like in Stripe you can retrieve a promo code by id:
Stripe::PromotionCode.retrieve(
'promo_1Hd0sBG03p6y1vChab7Jh6Zs',
)
However, I can not see a way to retrieve this by the actual customer facing code ex FIFTYOFF. Is there any way to do this?
It doesn't seem to make sense this is not possible, since this is all the data the user would have. I would need to either keep a local database duplicate of each Promo code and correlate with the customer facing code, or lookup all of my codes and iterate over them to find the actual promo code id.
The easiest solution is to use the List Promotion Codes API and pass the code parameter. This will return a list of Promotion Codes with that code and since it has to be unique, the list will only contain one element which is what you are after:
promotion_codes = Stripe::PromotionCode.list({
code: 'FIFTYOFF',
})
promotion_code_id = promotion_codes.data[0].id

Import Customer Refund scenario and got error 'Document is out of balance'

I try to import customer refund scenario but it got error as "Document is out of balance" like the below picture:
Do you have some applications imported along with Customer Refund?
In Acumatica you are not allowed to create Customer Refund that is not fully applied to some document.
So, if you are trying to create Customer refund without any applications(or if sum of application amounts is not equal to refund amount), you'll get this error.
So, either create document along with applications or create document On Hold(that is Hold checkbox selected).
Document having On Hold status considered as draft and can be saved unbalanced.

Stripe charge create amount to be dynamic

I'm trying to implement a stripe payment, and I know that stripe requires you to set the amount twice. Once at checkout and another on the server side.
I'm using web2py as my framework.
So my question is how do I make them match?
I made the server side dynamic via JS, but I'm struggling to the server side to have the same amount.
# Set your secret key: remember to change this to your live secret key in production
# See your keys here https://dashboard.stripe.com/account/apikeys
stripe.api_key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"
# Get the credit card details submitted by the form
token = request.POST['stripeToken']
# Create the charge on Stripe's servers - this will charge the user's card
try:
charge = stripe.Charge.create(
amount=1000, # how to make this portion match the check out amount
currency="usd",
source=token,
description="Example charge"
)
except stripe.error.CardError, e:
# The card has been declined
pass
is there away to the get more information?
The data-amount and data-currency Checkout configuration options are only used for display purposes. They're irrelevant to the actual charge's amount and currency.
To let your user specify the amount themselves, you could add an amount field to your form, that will be sent along with the "normal" Checkout parameters (stripeToken, stripeEmail, etc.).
Here's a simple JSFiddle to illustrate: https://jsfiddle.net/ywain/g2ufa8xr/
Server-side, all you'd need to do is get the amount from the POST parameters:
try:
charge = stripe.Charge.create(
amount=request.POST['amount']
# ...
Of course, in a real-world scenario, you should validate the amount field, both client-side and server-side. At the very least, you want to make sure that it's:
a strictly positive numerical value
above the minimum charge amount
below a reasonable maximum for your application

Resources