paypal checkout.js popup opens and then closes immediately - paypal-sandbox

<div id="paypal-button"></div>
<script src="https://www.paypalobjects.com/api/checkout.js"></script>
<script>
paypal.Button.render({
client: { sandbox: 'sandboxemailaddress',
production: 'dummyemailaddress'},
env: 'sandbox',
payment: function() {
var env = this.props.env;
var client = this.props.client;
return paypal.rest.payment.create(this.props.env, this.props.client, {
transactions: [
{
amount: {total: 20.00, currency: 'USD' },
locale: 'en_US',
enableShippingAddress: true,
shippingAddressEditable: false,
shippingAddressOverride: {
recipientName: 'John Public',
line1: '123 South East St',
line2: '',
city: 'Upland',
state: 'CA',
postalCode: '91711',
countryCode: 'US',
countryCode: 'US',
phone: '909-626-3777'
}
}
],
});
},
commit: true,
onAuthorize: function(data, actions) {
return actions.payment.execute().then(function() {
});
},
'#paypal-button');
</script>
Button displays w/o error being reported.
On clicking on the button the box opens up on the screen, the wait circle appears and then the box closs. Javascript console in Firefox reports:
window.paypal<["./node_modules/post-robot/src/drivers/receive/types.js"]/exports.RECEIVE_MESSAGE_TYPES< https://www.paypalobjects.com/api/checkout.js:3416:40
receiveMessage https://www.paypalobjects.com/api/checkout.js:1838:13
messageListener https://www.paypalobjects.com/api/checkout.js:1856:13

I had the same issue.
As soon as I added it, it worked:
paypal.Button.render({ <p>
client: { sandbox: 'AdZo0BCkNeg-xxxlongasssssString',
production: 'PRODUCTIONCLIENTIDSTRING'}, <p>
env: 'sandbox', // sandbox | production

change 'sandboxemailaddress' with Client ID.

Related

How do I create a custom connect stripe account and pass account id to payment intent method using firebase functions?

I am trying to collect and transfer payments using firebase cloud functions in my react native app. I'm using the stripe.accounts.create and stripe.paymentIntents.create functions as well as library axios. I'm really not too sure how to create the connect account and pass the account id created into the payment intent method. I get the following error in the firebase logs 'code: 'StripeInvalidRequestError: Can only apply an application_fee_amount when the PaymentIntent is attempting a direct payment (using an OAuth key or Stripe-Account header) or destination payment (using transfer_data[destination])'
when trying to run my code below. Can someone please assist? I don't think the connectAcc.id is null since I can see it in my stripe dashboard logs in the response body where the account is created:
Response body
{
"id": "acct_**********U5",
"object": "account",
"business_profile": {
"mcc": "5734",
"name": null,
"product_description": null,
"support_address": null,
"support_email": null,
"support_phone": null,
"support_url": null,
index.js file
const stripe = require('stripe')('**SK_LIVE**');
exports.payWithStripe = functions.https.onRequest((request, response) => {
const connectAcc = stripe.accounts.create({
type: 'custom',
email: 'name#gmail.com',
country: 'GB',
business_type: 'individual',
business_profile: {
mcc: '5734',
url: 'site.com',
},
individual: {
first_name: 'First',
last_name: 'Last',
dob : {
day: 1,
month: 10,
year: 1990
},
email: 'name#gmail.com',
phone: '+44xxxxxxx',
address: {
city: 'city',
country: 'GB',
line1: '1',
line2: 'Street Rd',
postal_code: 'XXX XXX'
}
},
tos_acceptance: {
date: Math.floor(Date.now() / 1000),
ip: request.connection.remoteAddress,
},
capabilities: {
card_payments: {requested: true},
transfers: {requested: true},
},
external_account: {
object: 'bank_account',
country: 'GB',
currency: 'gbp',
account_number: 'xxxxx',
routing_number: 'xxxxx',
accounter_holder_name: 'First Last',
account_holder_type: 'individual',
}
})
stripe.paymentIntents.create({
amount: request.body.amount,
currency: request.body.currency,
payment_method_types: ['card'],
payment_method: request.body.payment_method.id,
application_fee_amount: 20,
on_behalf_of: connectAcc.id,
transfer_data: {
destination: connectAcc.id,
},
confirm: true,
description: 'UniHome'
}
).then((charge) => {
response.send(charge);
})
.catch(err =>{
console.log(err);
})
});
Thanks.
connectAcc is not an account object — it's a Promise. That's what Stripe's SDK returns.
You'd have to resolve the Promise first, like:
let connectAcc = await stripe.accounts.create(...); let id = connectAcc.id or stripe.accounts.create(...).then(function(acct){let id = acct.id;} )

Dynamically setting up the PayPal Checkout Transaction using JASON

Depending on the goods being purchased I would like to create a JASON object to be placed into the Transaction area of the PAYPAL transaction. I keep failing no matter what I do. Following is the javascript code I am using to test:
paypal.Button.render({
env: 'sandbox',
client: {
sandbox: 'demo_sandbox_client_id'
},
payment: function (data, actions) {
var oAmount = {},
oAmount_details = {};
oAmount.total = '30.11';
oAmount.currency = "USD";
oAmount_details.subtotal = '30.00';
oAmount_details.tax = '00.11';
oAmount.details = oAmount_details;
return actions.payment.create({
transactions: [{
amount: oAmount
/*
amount: {
total: '30.11',
currency: 'USD',
details: {
subtotal: '30.00',
tax: '0.11'
}
}
*/
}]
});
},
onAuthorize: function (data, actions) {
return actions.payment.execute()
.then(function () {
window.alert('Thank you for your purchase!');
});
}
}, '#paypal-button');
*Note if you comment out:
amount: oAmount
and then uncomment:
amount: {
total: '30.11',
currency: 'USD',
details: {
subtotal: '30.00',
tax: '0.11'
}
}
then it will work.
Any help will be greatly appreciated.
fiddle

Meteor ms-seo static meta tags per route

I cant get SEO settings to work on a route basis.
What I've tried:
1) Setting it globally in seotest.js above client or server code.
SeoCollection = new Meteor.Collection("SeoCollection");
Router.route('/', function () {
this.render('index');
SeoCollection.update(
{
route_name: 'index'
},
{
$set: {
route_name: 'index',
title: 'indexpagetestl',
meta: {
'description': 'Manuel Schoebel is an experienced web developer and startup founder. He develops but also consults startups about internet topics.'
},
og: {
'title': 'About - Manuel Schoebel',
'image': 'http://manuel-schoebel.com/images/authors/manuel-schoebel.jpg'
}
}
},
{
upsert: true
}
);
Router.route('/notindex', function () {
this.render('notindex');
SeoCollection.update(
{
route_name: 'notindex'
},
{
$set: {
route_name: 'notindex',
title: 'notindexpagetestl',
meta: {
'description': 'Manuel Schoebel is an experienced web developer and startup founder. He develops but also consults startups about internet topics.'
},
og: {
'title': 'About - Manuel Schoebel',
'image': 'http://manuel-schoebel.com/images/authors/manuel-schoebel.jpg'
}
}
},
{
upsert: true
}
);
}
I've also tried to same code inside (Meteor.isClient) and (Meteor.isServer) code, but neither works.
I am able to get the initial SEO meta tags working with:
Meteor.startup(function() {
if(Meteor.isClient){
return SEO.config({
title: 'Manuel Schoebel - MVP Development',
meta: {
'description': 'Manuel Schoebel develops Minimal Viable Producs (MVP) for Startups'
},
og: {
'image': 'http://manuel-schoebel.com/images/authors/manuel-schoebel.jpg'
}
});
}
});

Ember-data loading async and order results according with property

I'm learning about ember/ember-data and would like to fetch some data from server and order it.
My json data is something like
{
'ninjas': [
{ id: '1', name: 'Ninja 1', age: 23},
{ id: '2', name: 'Ninja 2', age: 27},
{ id: '3', name: 'Ninja 3', age: 22}
],
'clans': [
{ id: '1566', title: 'Foot Clan', ninja_ids: ['1', '2']},
{ id: '8941', title: 'Hand Clan', ninja_ids: ['3']}
]
}
The templates are
<script type="text/x-handlebars" data-template-name="clans">
<div>Clans</div>
<ul>
{{#each controller}}
<li>
{{#link-to 'clan' this}}{{title}}{{/link-to}}
</li>
{{/each}}
</ul>
</script>
<script type="text/x-handlebars" data-template-name="clan">
<div>{{title}}</div>
{{#each fetchedNinjas}}
<ul>
<li>{{fetchedNinjas}}</li>
</ul>
{{/each}}
</script>
Here is the basic App script:
var App = Ember.Application.create();
App.AplicationStore = DS.Store.extend({
revision: 12,
adapter: DS.RESTAdapter.create({})
});
App.Router.map(function() {
this.resource('ninjas');
this.resource('clans');
this.resource('clan', {path: 'clans/:clan_id'});
});
The ninja script is here:
App.Ninja = DS.Model.extend({
name: DS.attr('string'),
age: DS.attr('number'),
clans: DS.hasMany('clan')
});
App.NinjasRoute = Ember.Route.extend({
model: function (params, transition, queryParams) {
return this.store.find('ninja');
}
});
Here is the Clan Model, ClansRoute, ClanRoute
App.Clan = DS.Model.extend({
title: DS.attr('string'),
ninjas: DS.hasMany('ninja', {async: true})
});
App.ClansRoute = Ember.Route.extend({
model: function (params, transition, queryParams) {
return this.store.find('clan');
}
});
App.ClanRoute = Ember.Route.extend({
model: function (params, transition, queryParams) {
return this.store.find('clan', params.clan_id);
}
});
I think that I should get the related ninja data on ClanController and then order it, but I don't know how to proceed.
App.ClanController = Ember.ObjectController.extend({
fetchedNinjas: function () {
//should I use a promise here?
}.property('ninjas')
});

Durandal 2 upgrade redirect issue

Hello and thanks for taking a look at my issue.
I have been migrating my SPA application to use the Durandal 2.0 library, following the sage advice from my oft savior, John Papa. And now that I have completed the upgrade process, I find a strange behavior (or a lack of behavior) when I try to navigate using my menu buttons. Specifically what isn't happening is the browser doesn't redirect to the new page. The interesting thing is that the browser address bar is populated properly and if I simply click in the address bar and press enter (hard reload), I am redirected as expected.
I've looked around and this is not caused due to any security check/redirect which I have seen other discussing elsewhere. Durandal code is unmodified.
js on pages can be quite trivial:
define([], function () {
console.log("welcome loaded");
var vm = {
title: 'Welcome'
};
return vm;
});
So my guess is its something in my configuration of durandal.
main.js:
require.config({
paths: {
'text': '../Scripts/text',
'durandal': '../Scripts/durandal',
'plugins': '../Scripts/durandal/plugins',
'transitions': '../Scripts/durandal/transitions',
'knockout': '../Scripts/knockout-2.3.0',
'bootstrap': '../Scripts/bootstrap',
'jquery': '../Scripts/jquery-1.9.1'
},
shim: {
'bootstrap': {
deps: ['jquery'],
exports: 'jQuery'
}
}
});
define('jquery', function () { return jQuery; });
define('knockout', ko);
define(['durandal/system', 'durandal/app', 'durandal/viewLocator'],
function (system, app, viewLocator) {
// Enable debug message to show in the console
system.debug(true);
app.configurePlugins({
router: true,
dialog: true,
widget: true
});
app.start().then(function () {
toastr.options.positionClass = 'toast-bottom-right';
toastr.options.backgroundpositionClass = 'toast-bottom-right';
// When finding a viewmodel module, replace the viewmodel string
// with view to find it partner view.
viewLocator.useConvention();
// Adapt to touch devices
// app.adaptToDevice();
//Show the app by setting the root view model for our application.
app.setRoot('viewmodels/shell', 'entrance');
});
});
shell.js:
define(['../../Scripts/durandal/plugins/router', 'viewmodels/config', 'services/datacontext'], function (router, config, datacontext) {
function addSession(item) {
router.navigate(item.hash);
}
function boot() {
// $(".page-splash-message").text("Configuring routes...");
router.makeRelative({ moduleId: 'viewmodels' });
router.map(config.routes);
router.buildNavigationModel();
$(".page-splash-message").text("Let's make traxx..!");
return router.activate();
}
function failedInitialization(error) {
var msg = 'App initialization failed: ' + error.message;
}
return {
addSession: addSession,
adminRoutes: adminRoutes,
profileRoutes: profileRoutes,
visitorRoutes: visitorRoutes,
router: router,
activate: function () {
datacontext.primeEditData().then(boot).fail(failedInitialization);
}
};
});
routes in config.js
define(['../../Scripts/durandal/plugins/router'], function (router) {
toastr.options.timeOut = 4000;
toastr.options.positionClass = 'toast-bottom-right';
var startModule = 'Welcome';
var serviceName = 'api/Zepher';
var imageSettings = {
imageBasePath: '../content/images/photos/',
unknownPersonImageSource: 'unknown_person.jpg'
};
var routes = [
{ route: '', moduleId: 'home/welcome', title: 'Welcome', nav: false, },
{ route: 'Welcome', moduleId: 'home/welcome', title: 'Welcome', nav: false, },
{ route: 'NotFound', moduleId: 'home/notFound', title: 'Not Found', nav: false, },
{ route: 'Roadmap', moduleId: 'home/roadmap', title: 'Roadmap', nav: false, },
{ route: 'Register', moduleId: 'account/register', title: 'Register', nav: true, caption: '<i class="fa fa-user"></i> Register' },
{ route: 'RegisterAccounts', moduleId: 'account/registerAccounts', title: 'Register Accounts', nav: false, caption: '<i class="fa fa-key"></i> Register Accounts', },
];
return {
debugEnabled: ko.observable(true),
imageSettings: imageSettings,
servicetitle: serviceName,
startModule: startModule,
router: router,
routes: routes,
activate: function () {
console.log("config activate called");
router.makeRelative({moduleId: 'viewmodels'});
router.map(routes);
router.buildNavigationModel();
//sets up conventional mapping for
//unrecognized routes
router.mapUnknownRoutes('home/nontFound', 'not-found');
//activates the router
return router.activate();
// no longer needs a start module
}
};
});
found what I was missing in my upgrade, so I thought I'd share what I've learned.
Seems I forgot to update my Shell.html file.
From this:
<div>
<header>
<!--ko compose: {view: 'shared/nav', afterCompose: router.afterLogging, transition: 'entrance' } --><!--/ko-->
</header>
<section id="content" class="main">
<!--ko compose: {model: router.activeItem, afterCompose: router.afterCompose, transition: 'entrance', cacheViews: true } --><!--/ko-->
</section>
<footer>
<!--ko compose: {view: 'shared/footer'} --><!--/ko-->
</footer>
</div>
to This:
<div>
<header>
<!--ko compose: {view: 'shared/nav', afterCompose: router.afterLogging, transition: 'entrance' } --><!--/ko-->
</header>
<section id="content" class="main container-fluid page-host" data-bind="router: { transition: 'entrance', cacheViews: true }">
</section>
<footer>
<!--ko compose: {view: 'shared/footer'} --><!--/ko-->
</footer>
</div>

Resources