Paypal recurring payments with variable amount 2 (in Spain) - ruby-on-rails

some days ago, I wrote this post regarding Paypal recurring payments with variable amount Paypal recurring payments with variable amount
I marked it as fixed, however it is not.
First, I decided to develop approach 1 (by removing old profile and creating a new one). This worked. But, after that I realized, that I didn´t cover all my requirements. So finally, the right approach for me is number 2. This means, as #Andrew Angell suggested, I will develop a custom billing system that bills the customers. For that, I will create Billing Agreements and I will use the returned ids to execute Reference transactions with the amount I need and whenever I need. So far, it´s right?
According to Paypal docs, this is possible: https://developer.paypal.com/docs/classic/express-checkout/integration-guide/ECReferenceTxns/
So, I´m trying to follow the steps, so first a execute a setExpressCheckout:
# Paypal setExpressCheckout
def setExpressCheckout(billingType, returnURL, cancelURL, price, description)
#api = PayPal::SDK::Merchant::API.new
if billingType == "credit-card"
billingType = "Billing"
else
billingType = "Login"
end
#set_express_checkout = #api.build_set_express_checkout({
SetExpressCheckoutRequestDetails: {
ReturnURL: returnURL,
CancelURL: cancelURL,
LocaleCode: "US",
LandingPage: billingType,
PaymentDetails: [{
NotifyURL: returnURL,
OrderTotal: {
currencyID: "EUR",
value: price
},
ShippingTotal: {
currencyID: "EUR",
value: "0"
},
TaxTotal: {
currencyID: "EUR",
value: "0"
},
PaymentDetailsItem: [{
Name: description,
Quantity: 1,
Amount: {
currencyID: "EUR",
value: price
},
}],
PaymentAction: "Authorization" # To authorize and retain the funds, and when booking is confirmed capture them.
}],
BillingAgreementDetails: [{
BillingType: "MerchantInitiatedBillingSingleAgreement",
BillingAgreementDescription: description
}]
}
})
# Make API call & get response
#express_checkout_response = #api.set_express_checkout(#set_express_checkout)
# Access Response
if #express_checkout_response.success?
#token = #express_checkout_response.Token
puts "setExpressCheckout completed OK :)"
#paypal_url = #api.express_checkout_url(#express_checkout_response)
else
puts "setExpressCheckout KO :("
#express_checkout_response.Errors
puts "#express_checkout_response=" + #express_checkout_response.inspect
end
#express_checkout_response
end
However, I get this error:
#LongMessage="Merchant not enabled for reference transactions", #ErrorCode="11452"
It´s quite clear, just need to contact Paypal support guys and ask them to enable Reference transactions in my Paypal sandbox account. Right? I already did it and I´m just waiting.
However, what really worries me, is that I called Paypal support and they told me that this approach will not work in Spain. Although it´s in the doc, it´s only working in UK. Is this true?
If it´s true, I´m really in a trouble, because as far as I know, Paypal doesn´t not support subscriptions with variable amount.

Paypal technical support guy has enabled my sandbox account to reference transactions. I have developed the logic and it´s working. At least, in Sandbox and in Spain.
So, I will assume, it works.
Bad the Paypal guy on the phone that told me it wasn´t possible.

Related

Can't submit localized text for In App Purchases with Fastlane to Appstore Connect

I'm currently using the (deprecated) Spaceship API to create subscription in-app-purchases. Besides Fastlane I'm not using Ruby at all, so I'm really a beginner when it comes to data types etc. in Ruby.
To have it better configurable I outsourced everything to a Json file:
{
"subscriptionFamily": {
"familyName": "TEST-FAMILY",
"localizedDescriptions": {
"en-US": {
"subscription_name": "Unlock all",
"name": "Get access to everything"
},
"de-DE": {
"subscription_name": "Blabla",
"name": "Blablabla"
}
}
}
Then, within Fastlane, I read the Json file first with that method:
def get_subscription_config
file = File.open $subscription_config_path
JSON.load file
rescue StandardError => e
UI.error("Couldn't find or read the subscription configuration file")
end
subscription_family = subscription_config['subscriptionFamily']
Then, eventually, after logging in through Spaceship, I create the subscription family:
app.in_app_purchases.families.create!(
name: subscription_family['familyName'],
versions: subscription_family['localizedDescriptions'],
product_id: first_subscription['subscriptionId'],
reference_name: first_subscription['referenceName']
)
This throws an error:
[!] The request could not be completed because:
You must enter a Subscription Group Display Name for English (U.S.). You must enter a Subscription Group Display Name for German. You must enter a Subscription Group Display Name for the following localizations: English (U.S.), German.
Now the thing that confuses me the most: When I add the data from the Json into a variable like that and then pass on the variable into the create method, then everything works!
localizationData = {
"en-US": {
"subscription_name": 'Unlock all features',
"name": 'Get access to all features within the app.'
},
"de-DE": {
"subscription_name": 'Alle Funktionen freischalten',
"name": 'Schalte alle Inhalte innerhalb der App frei.'
}
}
app.in_app_purchases.families.create!(
name: subscription_family['familyName'],
versions: localizationData,
product_id: first_subscription['subscriptionId'],
reference_name: first_subscription['referenceName']
)
I already tried to compare the types, but they are both hashes. I also tried to wrap the Json data into an OpenStruct: OpenStruct.new(subscription_family['localizedDescriptions']). This actually doesn't throw an error anymore, and the subscription group is created, but without submitting the metadata to AppStore connect. The localization area there just stays empty.
Does anyone know what I'm doing wrong? Why are both the data from the variable and from the Json a hash but the one can be processed by Fastlane, the other can't?
Would be awesome to get some assistance on that!

Stripe Subscription update the plan immediately with full amount

I'm looking to update the customer's subscription, and the new plan price will be deducted immediately.
Consider the following scenario:
User is on Plan A($15 per month) and wants to update to Plan B($25 per month) in the middle of the month.
I want the user to charge $25 right away rather than prorate - I don't want the difference will be charged to the customer.
I also try with proration_behavior='always_invoice' However, it is charge $10. I need $25 charged right away.
subscription = Stripe::Subscription.retrieve('sub_49ty4767H20z6a')
Stripe::Subscription.update(
subscription.id,
{
cancel_at_period_end: false,
proration_behavior: 'none',
items: [
{
id: subscription.items.data[0].id,
price: 'price_1LcBtVHhBkzUOaGo0gvFmaMS'
}
]
}
)
I see you’re looking to update a subscription without any prorations and to immediately charge for the upgraded price. The way to achieve this would be by specifically passing proration_behavior: ‘none’ and billing_cycle_anchor: ‘now’. Your code will look something like this:
Stripe::Subscription.update(
subscription.id,
{
cancel_at_period_end: false,
billing_cycle_anchor: ‘now’,
proration_behavior: ‘none’,
items: [
{
id: subscription.items.data[0].id,
price: 'price_xxxxxxx'
}
]
}
)
Please note that this changes the billing cycle of the subscription and to learn more about billing_cycle_anchor please visit here.
You can achieve it with proration_behavior and billing_cycle_anchor.
You only need to pass these two properties while updating your subscription details using stripe API.
subscription = Stripe::Subscription.retrieve('sub_49ty4767H20z6a')
Stripe::Subscription.update(
subscription.id,
{
cancel_at_period_end: false,
proration_behavior: 'none',
billing_cycle_anchor: 'now',
items: [
{
id: subscription.items.data[0].id,
price: 'price_1LcBtVHhBkzUOaGo0gvFmaMS'
}
]
}
)

How to integrate SCA Stripe Checkout with Stripe Connect using Rails 5

I've been trying to enable payments to users (sellers in this case) on my site. I've managed to allow the seller to set up their own Stripe account, and then their Stripe account ID is saved in the database.
However, I can't manage to allow people to pay the sellers. I've been looking at the Stripe docs and although very detailed, I can't figure out where everything is meant to go. I would like something like this:
I have got a new charge view, and this code is supposed to be in it I think:
// Initialize Stripe.js with the same connected account ID used when creating
// the Checkout Session.
var stripe = Stripe('pk_test_CscsJfPdlaNBpLla09y0aA6W', {
stripeAccount: '{{CONNECTED_STRIPE_ACCOUNT_ID}}'
});
stripe.redirectToCheckout({
// Make the id field from the Checkout Session creation API response
// available to this file, so you can provide it as parameter here
// instead of the {{CHECKOUT_SESSION_ID}} placeholder.
sessionId: '{{CHECKOUT_SESSION_ID}}'
}).then(function (result) {
// If `redirectToCheckout` fails due to a browser or network
// error, display the localized error message to your customer
// using `result.error.message`.
});
I've also got a Charges Controller, but I'm not sure if this is meant to be there:
session = Stripe::Checkout::Session.create({
payment_method_types: ['card'],
line_items: [{
name: "Cucumber from Roger's Farm",
amount: 200,
currency: 'gbp',
quantity: 10,
}],
payment_intent_data: {
application_fee_amount: 200,
},
success_url: 'https://example.com/success',
cancel_url: 'https://example.com/cancel',
}, {stripe_account: '{{CONNECTED_STRIPE_ACCOUNT_ID}}'})
How do I Initialize Stripe.js with the right account ID? Where is this code meant to be? Do I need more?
Any help would be massively appreciated. Thanks.

Getting Rating for an App from Apple AppStore

I want to create a report regarding my App's rating in three dimensions - date, Country and App Version (I know that from Android I can get in a query only Date+Another Dim, not quite sure how it works with Apple...). I found the "Reporter" (https://help.apple.com/itc/appsreporterguide/#/itcbd9ed14ac) but it allows me only finance reports... I also saw the RSS option - only this option gives me the "last X reviews"' and I just want an aggregated data (lets say - for each day, how many 1 star rating, 2 star rating etc'...)
If someone can help me with how to do so (preferably in bash/python script), I'd really appriciate it. Thank you!
The easiest way to get them out of iTunes Connect is probably with Spaceship. (App > Activity > Ratings & Reviews
# Get reviews for a given store front
reviews = ratings.reviews("US") # => Array of hashes representing review data
https://github.com/fastlane/fastlane/blob/master/spaceship/docs/iTunesConnect.md#app-ratings--reviews
The Appfigures API can give you ratings and reviews for iOS and Android apps.
The following request will give you the last 50 reviews from any country, but you can easily get more reviews, limit by country/version/etc.
GET https://api.appfigures.com/v2/reviews?count=50
While will give you something like this:
{
"total": 140,
"pages": 28,
"this_page": 1,
"reviews": [{
"author": "DeveloperToDeveloper",
"title": "Just Spectacular",
"review": "Finally able to remove the ads! The description is hilarious!! Thanks!!!",
"original_title": null,
"original_review": null,
"stars": "5.00",
"iso": "US",
"version": "1.2",
"date": "2017-05-19T17:05:00",
"product": 6567539,
"weight": 0,
"id": "5561747L7xnbsMRu8UbPvy7A71Dv6A=="
}]
}
Here's how you'd do it with Python:
import requests
USERNAME = 'USERNAME'
PASSWORD = 'PASSWORD'
APP_KEY = 'APP_KEY'
BASE_URI = "https://api.appfigures.com/v2/"
# Helper function for auth and app_key
# first / in uri is optional
def make_request(uri, **querystring_params):
headers = {"X-Client-Key": APP_KEY}
auth =(USERNAME, PASSWORD)
return requests.get(BASE_URI + uri.lstrip("/"),
auth=auth,
params=querystring_params,
headers=headers)
# Get the last 50 reviews for all of our apps
reviews_response = make_request("/reviews",
count=50)
assert 200 == reviews_response.status_code
assert 0 < len(reviews_response.json())
# Use the response to sum up ratings, analyze review text, etc.
FYI - Reviews and ratings are separate for apps, and while the 5 star rating on a review contributes to the total rating, there could also be ratings that aren't associated with a written review.
Those can be retrieved using the Ratings route.

Is there any alternative for Reference Transaction in Paypal REST API?

After some time of researching and exploring the Paypal REST API documentation, I've found that currently reference transaction is available only in Paypal Classic API but not in Paypal REST API as stated in this StackOverflow post so I'm trying to find an alternative to bill users with different amounts every month.
Integrated Paypal REST API in my Rails 4 application. I'm trying to create agreements with auto-billing plans without charging real amount, and I planned to use set-balance to charge the remaining amounts and bill the users with outstanding amount. Eventually I've searched through the methods in paypal-sdk-rest but there's no method for me to set an outstanding balance on the agreement object.
And now I'm in stuck. Is there a Ruby method call to set and bill the outstanding balance to the agreements, or perhaps another way of charging users with different amounts every month?
A way I'd think of is to send invoices to users manually by using the Invoice object in REST API, but I prefer to bill users using agreements instead. Using Classic API might be the best option in this case but REST is still a better choice for future.
Hope to get reference transaction works in REST API very soon.
Plan:
plan = Paypal::Plan.new({
name: "Test Plan",
description: "Test recurring plan",
type: "infinite",
payment_definitions: [{
name:"Free Trial",
type:"TRIAL",
frequency:"MONTH",
frequency_interval:"1",
amount: {
value: "0.00",
currency: "USD"
},
cycles: "1"
},
{
name:"Standard Package",
type:"REGULAR",
frequency:"MONTH",
frequency_interval:"1",
amount: {
value: "0.01",
currency: "USD"
},
cycles: "11"
}],
merchant_preferences: {
setup_fee: {
value: "0",
currency: "USD"
},
auto_bill_amount: "YES",
return_url: return_url,
cancel_url: cancel_url,
}
})
Agreement:
agreement = Paypal::Agreement.new({
name: "Monthly billing",
description: "Billing Agreement",
start_date: (Date.today+ 1.month).strftime("%Y-%m-%dT%H:%M:%SZ"),
payer: {
payment_method: "paypal",
},
plan: {
id: Settings.plan_id
}})

Resources