How to setup Paypal subscriptions with multiple currencies? - paypal

For each product we do the following:
When a new product is added, create a new Product with POST /v1/catalogs/products
Using the product_id from step 1, create a new plan POST /v1/billing/plans
Whenever a customer clicks "Subscribe" button, we create a new subscription using plan_id from step 2 with POST /v1/billing/subscriptions
Problem: When creating the subscription we are able to change the price the customer will be billed by passing the plan object to POST /v1/billing/subscriptions endpoint to override the amount of the plan. However passing in a different currency throws an error:
"The currency code is different from the plan's currency code."
With that being said, is thereĀ a way to setup paypal subscriptions where we can pass in a different currency? Is it required to create a new plan for each currency because this does not seem like a good solution
We create a billing plan with the following body:
{
product_id: productId,
name: planName,
status: 'ACTIVE',
billing_cycles: [
{
frequency: {
interval_unit: 'MONTH',
interval_count: 1
},
tenure_type: 'REGULAR',
sequence: 1,
// Create a temporary pricing_scheme. This will be replaced
// with a variable amount when a subscription is created.
pricing_scheme: {
fixed_price: {
value: '1',
currency_code: 'CAD'
}
},
total_cycles: 0
}
],
payment_preferences: {
auto_bill_outstanding: true,
payment_failure_threshold: 2
}
}
We create subscription with the following body (however passing in a different currency than the plan (CAD) throws an error):
{
plan_id: planId,
subscriber: {
email_address: email
},
plan: {
billing_cycles: [
{
sequence: 1,
pricing_scheme: {
fixed_price: {
value: amount,
currency_code: currency
}
}
}
]
},
custom_id: productId
};

Is it required to create a new plan for each currency
Yes

Related

Paypal Smart Button Integration - Is there a way i can add a discount coupon/SKU to the order.create function?

I have a Paypal Smart Button integration with my eCommerce site. The entire setup is: User clicks on the Paypal button -> makes a payment -> IPN call to my backend -> saves data to database. This flow is working fine for me.
I now want to be able to pass a discount SKU to Paypal so i can capture it in my database with the IPN call. Right now, only the discount amount ie being sent to Paypal depending on the coupon code used.
Here's my current code:
purchase_units: [{
description: "Zing Energy Patches",
amount: {
currency_code: currencyCode,
value: (basePrice + shippingPrice + tax - creditPrice).toFixed(2),
breakdown: {
item_total: {
currency_code: currencyCode,
value: basePrice
},
shipping: {
currency_code: currencyCode,
value: shippingPrice
},
tax_total: {
currency_code: currencyCode,
value: tax
},
discount:{
currency_code: currencyCode,
value: creditPrice
}
}
},
items: productsArray
}]
});```
I tried adding the discount as an item with negative value, but Paypal rejected the request stating that negative values are not allowed.

Magento2 - How to place order using graphql?

I am following this tutorial to process cart / checkout for placing orders using graphql. Magento GraphQl Tutorial. And we have installed stripe on magento(backend).
So we are facing issue while placing order, we have done few steps upto point 5.
Customer logs in get a authentication token
Create empty cart
Add product to cart
Set billing and shipping address for cart
Set payment method to stripe_payments (without card details)
How to set payment information and where to set ?
Placing order receiving error here
How can I set payment method and debit card details to cart using graphql and place an successful test order?
Make sure all steps ( 1 to 5 ) have been done without any issue. Please check the below steps for the mutation by which you can set the payment method and place the order.
Example: Use the setPaymentMethodOnCart mutation to set the payment method for your order. The value checkmo ("Check / Money order" payment method code) was returned in the query.
mutation {
setPaymentMethodOnCart(input: {
cart_id: "{ CART_ID }"
payment_method: {
code: "checkmo"
}
}) {
cart {
selected_payment_method {
code
}
}
}
}
Response:
If the operation is successful, the response contains the code of the selected payment method.
{
"data": {
"setPaymentMethodOnCart": {
"cart": {
"selected_payment_method": {
"code": "checkmo"
}
}
}
}
}
Set payment method and place order
Use the setPaymentMethodAndPlaceOrder mutation to set the payment method and place the order.
Request:
mutation {
setPaymentMethodAndPlaceOrder(input: {
cart_id: "{ CART_ID }"
payment_method: {
code: "checkmo"
}
}) {
order {
order_id
}
}
}
Response:
If the operation is successful, the response contains the order ID.
{
"data": {
"setPaymentMethodAndPlaceOrder": {
"order": {
"order_id": "000000001"
}
}
}
}
Note: Make sure "setPaymentMethodAndPlaceOrder mutation" is not deprecated in the current version of Magento 2.
First check the available payment method ( added from magneto dashboard only)
Then set that payment method and post the query
https://devdocs.magento.com/guides/v2.4/graphql/tutorials/checkout/checkout-payment-method.html

Inconsistency in Amount due data in NetSuite API

I am trying to pull the Amount remaining data from Invoices in NetSuite.
The problem is the data is very inconsistent.
First of all, they do not provide the Amount remaining in the Invoice's currency. Looks like they only provide it in USD. So I tried to convert to the target currency with exchange rate and it works fine 75% of the time.
Conversion: Amount due in Foreign currency = Amount due in API reponse/exchange rate
SAMPLE RESPONSE 1:
{
Invoices: [
{
amountRemaining: 6096.9,
currency: 2, <-- (GBP)
exchangeRate: 1.354865,
fxAmount: 4500,
status: open,
customFieldList: { },
xmlns:platform_common: urn:common_2017_2.platform.webservices.netsuite.com,
custom_segments: { },
custom_fields: { }
}
],
}
In sample 2, the exchange rate had to be around 1.3 but it is wrongly set as 0.76. However, the good thing is the Amount remaining is calculated according to the exchange rate and so the conversion with the above formula would still give me the correct amount due.
SAMPLE RESPONSE 2:
{
Invoices: [
{
amountRemaining: 58538.49,
currency: 2, <-- (GBP)
exchangeRate: 0.76009212,
fxAmount: 77015,
status: open,
customFieldList: { },
xmlns:platform_common: urn:common_2017_2.platform.webservices.netsuite.com,
custom_segments: { },
custom_fields: { }
}
],
}
However, in sample 3, the exchange rate is wrongly set as 1. And the Amount due should have been 21523.32. However, it is around 30000. Not sure how this information is calculated.
SAMPLE RESPONSE 3:
{
Invoices: [
{
amountRemaining: 30132.648,
currency: 2, <-- (GBP)
exchangeRate: 1,
fxAmount: 21523.32,
status: open,
customFieldList: { },
xmlns:platform_common: urn:common_2017_2.platform.webservices.netsuite.com,
custom_segments: { },
custom_fields: { }
}
],
}
How is the Amount due calculated? Am I looking at the wrong fields for the conversion?
Thanks in advance!

How to Specify NoShipping 1 with Express Checkout checkout.js v4

I have express checkout working with the latest checkout.js but do not need to show any shipping address. Since it's a digital good, the docs say I need noshipping set to 1. However, I can't figure out how that goes into the javascript.
I followed the basic integration steps and then used the REST API to execute the payment so I can charge to my server.
I've tried adding noshipping:1 all over the place within the javascript to create the payment with no luck. Here's what it looks like ( ignore compile issues as I'm just trying to show how I tried adding the noshipping:1 information):
payment: function() {
var env = this.props.env;
var client = this.props.client;
return paypal.rest.payment.create(env, client, {
transactions: [
{
amount: { total: '4.99', currency: 'USD' }
DOESNT WORK-->noshipping: 1
}
],
DOESNT WORK-->noshipping: 1
});
},
Does anyone know how to properly pass the noshipping information using the latest checkout.js?
OK, it appears that they have finally added support for this. It looks like this:
payment: {
transactions: [
{
amount: { total: '19.99', currency: 'USD' }
// Possibly there is also a 'custom' field we can specify here;
// https://stackoverflow.com/questions/46320753/
}
],
application_context: {
shipping_preference: 'NO_SHIPPING'
}
}
Got an "official" response from paypal support a week later:
Thank you for contacting PayPal Merchant Technical Services.
Unfortunately we do not have an option for the noshipping when using
REST API. That option is only available on the classic express
checkout which uses the NVP/SOAP API.
There it is. This fairly simple concept isn't possible with their latest SDK.
Yes, there's a way to specify NOSHIPPING as follows on PayPal-Python-SDK, as per your code:
payment: function() {
var env = this.props.env;
var client = this.props.client;
return paypal.rest.payment.create(env, client, {
transactions: [
{
amount: { total: '4.99', currency: 'USD' }
}
],
application_context: {
shipping_preferences: 'NO_SHIPPING',
}
});
},
I hope it helps.

Meteor: Publish using users profile properties rather than ID

I'm currently creating an app that will be used by multiple companies.
Each user has the following profile:
username: johnDoe
emails: [{address: "some#email.com", verified: true}],
profile: {
name: "John Doe",
companyId: "1234"
}
I then have a collection (called Companies) of company objects that contain configuration info, templates etc specific to that company.
{
id: "1234",
configuration: {},
templates: []
}
In order to isolate each companies data I want to only publish data that matches the users profile companyId to the companies id.
if (Meteor.isServer) {
// collection to store all customer accounts
Companies = new Mongo.Collection('Companies');
// publish collection
Meteor.publish("Company", function () {
return Companies.find({id: Meteor.user().profile.companyId});
})
}
This currently works if I hardcode the clinic Id
// publish collection
Meteor.publish("Company", function () {
return Companies.find({id: "1234");
})
But returns an empty cursor with the Meteor.user().profile.companyId.
This means that the issue is either that I'm using the wrong function or more probably, the publish is happening before the user().profile.companyId can run.
Anybody know what I'm doing wrong? and do you have any advice on what to read up about so that I have an understanding of this moving forwards?
Thanks
Try doing an explicit findOne() in your publish function:
// publish collection
Meteor.publish("Company", function () {
var user = Meteor.users.findOne({_id: this.userId});
if(user && user.profile && user.profile.companyId) {
return Companies.find({id: user.profile.companyId});
} else {
console.log(user);
return this.ready();
}
});