apple pay option not coming in stripe - python

backend
#app.route('/create-payment-intent', methods=['POST'])
def create_payment():
try:
data = json.loads(request.data)
# Create a PaymentIntent with the order amount and currency
intent = stripe.PaymentIntent.create(
amount=calculate_order_amount(data['items']),
currency='usd',
automatic_payment_methods={
'enabled': True,
},
)
return jsonify({
'clientSecret': intent['client_secret']
})
except Exception as e:
return jsonify(error=str(e)), 403
frontend
export default function App() {
const [clientSecret, setClientSecret] = useState("");
useEffect(() => {
// Create PaymentIntent as soon as the page loads
fetch("/create-payment-intent", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ items: [{ id: "xl-tshirt" }] }),
})
.then((res) => res.json())
.then((data) => setClientSecret(data.clientSecret));
}, []);
const appearance = {
theme: "stripe",
};
const options = {
clientSecret,
appearance,
};
return (
<div className="App">
{clientSecret && (
<Elements options={options} stripe={stripePromise}>
<CheckoutForm />
</Elements>
)}
</div>
);
}
here is my stripe code where i am expecting google pay to come but it is not coming. I am using live stripe acccount for testing . https://dev.polyverse.app/pay here is the my application you can check.

The Payment Element also supports Google Pay and Apple Pay [0]. There is no need to implement a separate Payment Request button.
Google Pay and Apple Pay are unavailable for merchants and customers in India on Stripe Checkout and Stripe Elements [1] which is probably why you're not seeing these payment method options.
If it helps, I do see Google Pay and Apple Pay as an option to pay with on the URL you've provided.
[0]https://stripe.com/docs/payments/accept-a-payment?platform=web&ui=elements#apple-pay-and-google-pay
[1]https://support.stripe.com/questions/supported-payment-methods-currencies-and-businesses-for-stripe-accounts-in-india

Related

Stripe IntegrationError: stripe.redirectToCheckout: You must provide one of lineItems, items, or sessionId

I've got a Django website and I'm trying to integrate Stripe using Django the Stripe API on the backend and Vue.js on the frontend. However, when I try to run the checkout link that's supposed to redirect me to the payment processing page, I get the following error:
Error: IntegrationError: stripe.redirectToCheckout: You must provide one of lineItems, items, or sessionId.
at new r (https://js.stripe.com/v3/:1:6143)
at Js (https://js.stripe.com/v3/:1:165350)
at $s (https://js.stripe.com/v3/:1:165646)
at https://js.stripe.com/v3/:1:166758
at Qs (https://js.stripe.com/v3/:1:166769)
at nc (https://js.stripe.com/v3/:1:167275)
at Ec.redirectToCheckout (https://js.stripe.com/v3/:1:188030)
at http://localhost:8000/dashboard/myaccount/teams/plans/:342:39
Here's the Vue.js method responsible for this:
<script src="https://js.stripe.com/v3/"></script>
<script>
const PlansApp = {
data() {
return {
}
},
delimiters: ['[[', ']]'],
methods: {
subscribe(plan) {
console.log('Subscribe:', plan);
const stripe = Stripe('{{ stripe_pub_key }}');
fetch('/dashboard/myaccount/teams/api/create_checkout_session/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': '{{ csrf_token }}'
},
body: JSON.stringify({
'plan': plan
})
})
.then(function(response) {
return response.json()
})
.then(function(session) {
console.log(session)
return stripe.redirectToCheckout({ sessionId: session.sessionId })
})
.then(function(result) {
if (result.error) {
console.log('Error:', result.error.message)
}
})
.catch(function(error) {
console.log('Error:', error);
});
}
}
}
Vue.createApp(PlansApp).mount('#plans-app')
</script>
And here's the Django code that creates the session on the backend:
#login_required
def create_checkout_session(request):
stripe.api_key = settings.STRIPE_SECRET_KEY
data = json.loads(request.body)
plan = data['plan']
if plan == 'basic':
price_id = settings.STRIPE_BASIC_PRICE_ID
else:
price_id = settings.STRIPE_PRO_PRICE_ID
try:
checkout_session = stripe.checkout.Session.create(
client_reference_id = request.user.userprofile.active_team_id,
success_url = '%s%s?session_id={CHECKOUT_SESSION_ID}' % (settings.WEBSITE_URL, reverse('team:plans_thankyou')),
cancel_url = '%s%s' % (settings.WEBSITE_URL, reverse('team:plans')),
payment_method_types = ['card'],
mode = 'subscription',
line_items = [
{
'price': price_id,
'quantity': 1
}
]
)
return JsonResponse({'sessionId': checkout_session['id']})
except Exception as e:
return JsonResponse({'error': str(e)})
I'm struggling to find out why I'm getting the error that I'm getting and would be grateful for any help!
I guest the problem come from the 'success_url' and the 'cancel_url'.
Try to add http:// or https:// in your url
Cordially

Anything similar to Python Request.session() but on Node.js

I have a web scraping application written completely in python. The information that I am web scraping is behind a login and I am using Request.session to save login sessions. I am trying to port the code to Node.js and wasn't able to find anything similar to request.session on Node.js. Please let me know if such a thing exists. Thank you.
Your best bet is using axios, which allows for extensive customization of request headers and types of authentication.
You can add axios-cookiejar for cookie management.
Simple example:
const axios = require('axios').default;
const axiosCookieJarSupport = require('axios-cookiejar-support').default;
axiosCookieJarSupport(axios);
// you can add an Authorization header to all requests:
// axios.defaults.headers.common['Authorization'] = 'Bearer token';
const cookie = 'lang=en; token=hello';
const body = {message: 'I\'m a message body'};
axios.post(url, body, {
auth: {
username: 'username',
password: 'mypassword',
},
headers: {
'Cookie': cookie,
'Content-Type': 'application/json',
},
})
.then(res => console.log(res))
.catch(err => console.error(err));
Old Answer:
I believe the Request object of the default HTTP server does not have what you are looking for.
But if you opted to use the Express framework, you could find similar functionalities in the express-session package.
To ilustrate it's capabilities and simplicity, here's a slightly tweaked version of the code example provided in their documentation:
const express = require('express')
const parseurl = require('parseurl')
const session = require('express-session')
const app = express()
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
}));
app.use((req, res, next) => {
if (!req.session.views) {
req.session.views = {}
}
// get the url pathname
const pathname = parseurl(req).pathname;
// count the views
req.session.views[pathname] = (req.session.views[pathname] || 0) + 1;
next();
});
app.get('/foo', (req, res, next) => {
res.send('you viewed this page ' + req.session.views['/foo'] + ' times');
});
app.get('/bar', (req, res, next) => {
res.send('you viewed this page ' + req.session.views['/bar'] + ' times');
});
app.use((req, res, next) => {
if (res.headersSent) {
return next();
} else {
console.error('Not found');
const err = new Error('Not Found');
err.status = 404;
return next(err);
}
});
app.use((err, req, res, next) => {
console.error(req.app.get('env') === 'production' ? err.message : err.stack);
if (res.headersSent) {
return next(err);
}
res.status(err.status || 500);
res.send(`${err.status} - ${err.message}`);
});
const http = require('http');
const server = http.createServer(app).listen(3000);
server.on('error', (e) => {
console.log('>>> Server error');
console.error(e);
});
console.log(`>>> Server running on localhost:3000`);

Python/Django with Stripe: Error in Post request in creating stripe subscription

This is my first time using stripe does this look familiar to anyone?
So I am able to see that a token is being created upon payment, but instead of being redirected to my template, i throws this error below!
ERROR
>**InvalidRequestError:**
>Request req_d5BvUPtlpLrsG5: Received unknown parameter: source
>Request Method: POST
>Django Version: 2.1
>Exception Type: InvalidRequestError
>Exception Value:
>**Request req_d5BvUPtlpLrsG5: Received unknown parameter: source**
CODE
def PaymentView(request):
user_membership = get_user_membership(request)
selected_membership = get_selected_membership(request)
publishKey = settings.STRIPE_PUBLISHABLE_KEY
if request.method == "POST":
try:
token = request.POST['stripeToken']
subscription = stripe.Subscription.create(
customer=user_membership.stripe_customer_id,# id on User Membership Model
items=[
{
"plan": selected_membership.stripe_plan_id,
},
],
source=token # 4242424242424242
)
return redirect(reverse('memberships:update-transactions',
kwargs={
'subscription_id': subscription.id
}))
except stripe.error.CardError as e:
messages.info(request, "Your card has been declined")
context = {
'publishKey': publishKey,
'selected_membership': selected_membership
}
return render(request, "path/templategoeshere.html", context)
It looks like you need to remove the source=token key value pair in the stripe.Subscription.create() method.
So, you should have something more like:
def PaymentView(request):
user_membership = get_user_membership(request)
selected_membership = get_selected_membership(request)
publishKey = settings.STRIPE_PUBLISHABLE_KEY
import stripe
stripe.api_key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"
if request.method == "POST":
try:
token = request.POST['stripeToken']
print(token) # WHAT IS PRINTED OUT HERE?
subscription = stripe.Subscription.create(
customer=user_membership.stripe_customer_id,
items=[
{
"plan": selected_membership.stripe_plan_id,
},
]
)
return redirect(reverse('memberships:update-transactions', kwargs={ 'subscription_id': subscription.id }))
except stripe.error.CardError as e:
messages.info(request, "Your card has been declined")
The accepted arguments for the stripe.Subscription.create() object method are: customer (required), application_fee_percent, billing, billing_cycle_anchor, coupon, days_until_due, items, metadata, prorate, tax_precent, trial_end, trial_from_plan and trial_period_days (all optional).
This may help: https://stripe.com/docs/api/python#create_subscription
I went through the tutorial and the way I tried to solve this was by creating a source object instead of token object in the Javascript. So if you look at JS code below (copied from STRIPE API docs) you can see its now createSource.The source == the CC number which will be attached to their account.
Back in Django I create a stripe.Customer.create_source and then subsequently the stripe.Subscription.create after I have the card saved to account.. Since the default in Stripe Subscriptions is to auto charge subscription with the card attached to customer account it should charge the card immediately.
Just grab the source_id similar to how you did with token from the form in Django and then pass into stripe.Customer.create_source (obviously grab your Stripe customer id to pass in ass well).
// Create an instance of the card Element.
var card = elements.create('card', {style: style});
// Add an instance of the card Element into the `card-element` <div>.
card.mount('#card-element');
// Handle real-time validation errors from the card Element.
card.addEventListener('change', function(event) {
var displayError = document.getElementById('card-errors');
if (event.error) {
displayError.textContent = event.error.message;
} else {
displayError.textContent = '';
}
});
// Handle form submission.
var form = document.getElementById('payment-form');
form.addEventListener('submit', function(event) {
event.preventDefault();
form.addEventListener('submit', function(event) {
event.preventDefault();
stripe.createSource(card).then(function(result) {
if (result.error) {
// Inform the user if there was an error
var errorElement = document.getElementById('card-errors');
errorElement.textContent = result.error.message;
} else {
// Send the source to your server
stripeSourceHandler(result.source);
}
});
});
});
if request.method == 'POST':
try:
source = request.POST['stripeSource']
stripe.Customer.create_source(
user_membership.stripe_customer_id,
source=source)
stripe.Subscription.create(
customer=user_membership.stripe_customer_id,
items=[
{
"plan": selected_membership.stripe_plan_id,
},
])
messages.success(request, 'Your payment was completed!')
# stripe.Customer.create_source(type='')
except stripe.CardError as e:
messages.info(request, 'Your card has been declined!')
Note: Per their docs you can pass in the customer data (address, etc) in the JS object like below. You could maybe add to the form to have user enter in credit card address data etc so it passes into their stripe customer account if you want to.
// Create a source or display an error when the form is submitted.
var form = document.getElementById('payment-form');
var ownerInfo = {
owner: {
name: 'Jenny Rosen',
address: {
line1: 'Nollendorfstraße 27',
city: 'Berlin',
postal_code: '10777',
country: 'DE',
},
email: 'jenny.rosen#example.com'
},
};
form.addEventListener('submit', function(event) {
event.preventDefault();
stripe.createSource(card, ownerInfo).then(function(result) {
//rest of stripe js code.....
Hopefully this helps!!

How To Pagination Angular2 with Django Rest Framework API

I am trying to create a simple blog application using Angular2 with Django Rest Framework.
I am implementing pagination in Django, but I do not know how to rendering it in Angular.
API has the following structure.
Entries are paginated every 5 entries.
ng2app/src/app/models/entries.model.ts
export interface IEntries {
count: any,
next: any,
previous: any,
results: IResults[]
}
export interface IResults {
title: string,
body: string,
created_at: any,
updated_at: any
}
ng2app/src/app/services/entries.service.ts
import { Injectable } from "#angular/core";
import { Http } from "#angular/http";
import 'rxjs/add/operator/toPromise';
import { IEntries } from '../models/entries.model';
#Injectable()
export class EntriesService {
constructor(
private http: Http
){
}
getEntries(page: number){
return this.http
.get(`http://127.0.0.1:8000/api/entries/?limit=5&offset=` +((page * 5)-5))
.toPromise()
.then(response => response.json())
.catch(this.handleError);
}
private handleError(error: any) {
console.error('An error occurred', error);
return Promise.reject(error.message || error);
}
}
ng2app/src/app/services/entries.component.ts
import { Component, OnInit } from '#angular/core';
import { EntriesService } from '../services/entries.service';
import { IEntries } from '../models/entries.model';
#Component({
selector: 'my-entries',
templateUrl: '../templates/entries.component.html',
styleUrls: ['../static/entries.component.css']
})
export class EntriesComponent implements OnInit{
title = 'entries';
entries: IEntries[] = [];
error: any;
public constructor(
private entriesService: EntriesService,
){}
getEntires(page :number) {
this.entriesService
.getEntries(page)
.then(entries => this.entries = entries)
.catch(error => this.error = error);
}
ngOnInit() {
this.getEntires(1);
}
}
ng2app/src/app/templates/entries.component.html
<div class="container">
<h2>{{title}}</h2>
<div class="panel panel-default" *ngFor="let results of entries.results">
<div class="panel-heading">{{ results.title }}</div>
<div class="panel-body pre-wrap" ng-bind="multiLineText">{{ results.body }}</div>
<div class="panel-footer">{{ results.created_at | date}}</div>
</div>
<nav *ngIf="entries.count > 5">
(I want to display pagination here)
</nav>
</div>
In such a case, please help how to implement Pagination.
After implementing pagination in the Django backend, querying the backend would return results in the following format:
"data": {
"count": ,
"next": "",
"previous": "",
"results": []
}
count: The total number of items returned.
next: The URL to the next items after performing pagination
previous: The URL to the previous items after you have navigated to the next. set of items
results: The items requested for from the backend, paginated obviously i.e if pagination was set to 10 items and 15 were returned, results would return 10 items on the first request, then after navigating to the URL in next, results would return the remaining 5.
Service
#Injectable({
providedIn: "root"
})
export class OurService {
constructor(private http: HttpClient) {}
// Here,we make our request to the backend API, this observer takes in the backend
// api url as a parameter and performs a GET request
getAllTransactions(APIUrl: string): Observable<any> {
return this.http.get<>(APIUrl);
}
}
Component
#Component({
selector: "app-transactions",
templateUrl: "./transactions.component.html",
styleUrls: ["./transactions.component.scss"]
})
export class TransactionsComponent implements OnInit {
transactions: Transacton[];
transactionsUrl = "http://.../api/v1/transactions/"; //url to query for the transactions
next: string;
previous: string;
constructor(private transactionService: TransactionService) {}
ngOnInit(): void {
// On component initialization, load the transactions on the page
this.getTransactions(this.transactionsUrl);
}
getTransactions(url: string) {
this.transactionService.getAllTransactions(url).subscribe(res => {
this.transactions = res.data.results;
if (res.data.next) {
// set the components next transactions here from the response
this.next = res.data.next;
}
if (res.data.previous) {
// set the components previous transactions here from the response
this.previous = res.data.previous;
}
});
}
// function fetches the next paginated items by using the url in the next transactions
fetchNext() {
this.getTransactions(this.next);
}
// function fetches the previous paginated items by using the url in the previous transactions
fetchPrevious() {
this.getTransactions(this.previous);
}
HTML
<div class="page-buttons">
<button class="btn prev" (click)="fetchPrevious()">
</button>
<button class="btn next" (click)="fetchNext()">
</button>
</div>
You can try ngx-pagination for pagination in Angular 2+.

paypalrestsdk with Django integration issue

I am trying to setup Paypal express checkout with REST API but when I click checkout with Paypal I get modal window and it just spins forever.
Payment create view:
def payment_create(request):
logging.basicConfig(level=logging.INFO)
paypalrestsdk.configure({
'mode': settings.PAYPAL_MODE,
'client_id': settings.PAYPAL_CLIENT_ID,
'client_secret': settings.PAYPAL_CLIENT_SECRET
})
# Create payment object
payment = paypalrestsdk.Payment({
"intent": "sale",
# Set payment method
"payer": {
"payment_method": "paypal"},
# Set redirect urls
"redirect_urls": {
"return_url": "http://127.0.0.1:8000/checkout/payment_done/",
"cancel_url": "http://127.0.0.1:8000/checkout/payment_error/"},
# Set transaction object
"transactions": [{
"amount": {
"total": "10.00",
"currency": "USD"},
"description": "payment description"}]})
# Create Payment and return status
if payment.create():
print("Payment[%s] created successfully" % (payment.id))
request.session["paymentID"] = payment.id
# Redirect the user to given approval url
for link in payment.links:
if link.method == "REDIRECT":
print("Redirect for approval: %s" % (link.href))
return HttpResponseRedirect(link.href)
else:
print("Error while creating payment:")
print(payment.error)
Cart.html template:
<div id="paypal-button"></div>
<script src="https://www.paypalobjects.com/api/checkout.js" data-version-4></script>
<script>
paypal.Button.render({
env: 'sandbox', // Optional: specify 'sandbox' environment
payment: function(resolve, reject) {
var CREATE_PAYMENT_URL = 'http://127.0.0.1:8000/checkout/payment_create/';
paypal.request.post(CREATE_PAYMENT_URL)
.then(function(data) { resolve(data.paymentID); })
.catch(function(err) { reject(err); });
},
onAuthorize: function(data) {
// Note: you can display a confirmation page before executing
var EXECUTE_PAYMENT_URL = 'http://127.0.0.1:8000/checkout/payment_execute/';
paypal.request.post(EXECUTE_PAYMENT_URL,
{ paymentID: data.paymentID, payerID: data.payerID })
.then(function(data) { window.location.replace("http://127.0.0.1:8000/checkout/payment_done/") })
.catch(function(err) { window.location.replace("http://127.0.0.1:8000/checkout/payment_error/") });
}
}, '#paypal-button');
</script>
From logs looks like I am successfully creating payment object, but failing to redirect, in dev tools i am seeing this:
VM6073:1 Uncaught SyntaxError: Unexpected token < in JSON at position 0
at JSON.parse ()
at XMLHttpRequest. (https://www.paypalobjects.com/api/checkout.js:10511:38)
After researching online seems like json is expected but i am returning html? Can anyone point me in the right direction.
I am new to programming so any help is appreciated!

Categories

Resources