Add Discount to Braintree Rails Subscription - ruby-on-rails

I'm trying to add a discount object to a subscription with the braintree-rails gem, but it is not applied. I'm guessing my code must be wrong, but I can't find a working example.
discount = BraintreeRails::Discount.find(params[:subscription_promo])
subscription = #plan.subscriptions.build permitted_params[:subscription]
subscription.discounts << discount
# ...
subscription.save
When I dump discount, it is loaded properly. The subscription is created just fine, but at full price. The discount is not there. How can I add the discount to the subscription?
Update: I tried modifying the direct query, but that has not helped.
#subscription.raw_object.discounts = {add:[{inherited_from_id: discount.id}]}
Update 2: I also ran a direct Braintree request against the API with the request expected of the above code, and it worked. There's something wrong happening between setting it and saving.
Update 3: A workaround is possible by extracting the attributes of the BraintreeRails::Subscription object, using Braintree::Subscription to call the API, and using BraintreeRails::Subscription.find to load it back into the object. This is definitely not optimal, though, since it's not very clean, and requires an extra API call.

gem author here.
Unfortunately neither BraintreeRails nor the Braintree ruby gem supports the subscription.discounts << discount style of adding discounts to subscriptions at the moment.
As you can see in braintree ruby doc, the adding/updating/overriding addon/discounts API is a little too flexible to be wrapped in a single subscription.discounts << discount line.
If your setup of addon/discounts for subscription is simple and doesn't vary much, you can try create one plan for each desired combination, and then use the right plan to create the subscription.
If your setup is quite dynamic(in terms of price, billing cycle, quantity etc), use the Braintree API directly is probably your best option. E.g.:
result = Braintree::Subscription.create(
:payment_method_token => "the_payment_method_token",
:plan_id => "the_plan_id",
:add_ons => {
:add => [
{
:inherited_from_id => "add_on_id_1",
:amount => BigDecimal.new("20.00")
}
],
:update => [
{
:existing_id => "add_on_id_2",
:quantity => 2
}
],
:remove => ["add_on_id_3"]
},
:discounts => {
:add => [
{
:inherited_from_id => "discount_id_1",
:amount => BigDecimal.new("15.00")
}
],
:update => [
{
:existing_id => "discount_id_2",
:quantity => 3
}
],
:remove => ["discount_id_3"]
}
)

Related

Stripe API Invalid Request: Must provide source or customer

I'm working on the Stripe API and building a custom checkout function - My error is specifically telling me I must provide a source or customer. This is my controller for creating charges:
I thought I was successfully creating a source and/or customer with the following code (I also included the post logs on my stripe dashboard)
Stripe::Charge.create(
:amount => #amount,
:currency => 'usd',
:source => params[:stripeToken],
)
Stripe::Customer.create(
:email => params[:stripeEmail],
:source => params[:stripeToken]
)
"error": {
"code": "parameter_missing",
"doc_url": "https://stripe.com/docs/error-codes/parameter-missing",
"message": "Must provide source or customer.",
"type": "invalid_request_error"
}
}
I did go through the docs but I guess I'm still a little lost
Thanks for any assistance!
Update: here is the return of my API POST requests.
Update2: I see that a customer is being created when I send a charge.
Update 3: Source property is set to the stripeToken parameter, representing the payment method provided. The token is automatically created by Checkout. - this seems possibly connected to my issue - maybe it's not correctly posting?
So it did turn out to be a token request - since I was using a test card for test purposes I imagine I had to pass a test token to ensure that the test card would work.
I believe the Rails Params I was using (: source => params[:stripeToken]
) are fine for production but not when checking against given cards. In case someone comes across this as I did (and of course this probably isn't the first time it was asked on SO)
When using the Stripe API you see there is a token tab beside the test card numbers - I assumed those were optional or "for something else" for some reason. THEY ARE NOT.
You'll want to make sure the token matches whatever test card you plan on using (I think)
My Stripe controller now looks like this
Stripe::Charge.create({
:amount => #amount,
:currency => 'usd',
:source => 'tok_visa', #params[:stripeToken] might be for in production I think this is for testing.,
:description => 'Your Donation to Victoria University',
:statement_descriptor => 'Victoria University'
# it seems test tokens must be set as string.
})
Decided to leave my comments in there - because why not?
P.S You'll need different token types for different card payment types. If you switch cards - switch tokens as well !!!! - the tokens are tabbed beside the test card numbers.

what happens when you call includes on a relation/collection in Rails?

I have a situation where I call includes on a collection and it's exhibiting weird behavior.
In a test, I have this scenario where
=> apples
[]
=> apples.rotten
[
[0] #<Apples:0x007fdff8b49b70> {
:id => 1,
:user_id => 1,
}
]
and rotten is a scope on apple that uses includes and joins some tables together. The test that I'm running does indeed create an apple associated with the model with the calling methods correctly... but apples is still returning => []
=> self.apples
[]
=> self
{
:id => 1
...
}
The answer is to #reload apples.rotten. Oops.

ActiveMerchant recurring payment - cycles parameters has no effects?

I'm using ActiveMerchant to process a recurring payment. I want the payment to have a limited number of occurence but even if I pass the 'cycles' parameters my payment has no end or any trace of limited number of occurence when I go to see the results of my transaction in the sandbox site ??
Here is my gateway definition :
config.after_initialize do
ActiveMerchant::Billing::Base.mode = :test
paypal_options = {
login: "my_api.ca",
password: "QNBW72G3Q999999",
signature: "AFcWxV21C7fd0v3bYYYRCpSSRl31AmVtuyteuytuetwuytwtwEyY5cTGMA"
}
::MY_PAYMENT_GATEWAY = ActiveMerchant::Billing::PaypalCaGateway.new(paypal_options)
end
And here is my code to process the recurring payment :
response = MY_PAYMENT_GATEWAY.recurring(amount,
#publisher.credit_card.active_merchant_credit_card,
{:ip => request.remote_ip,
:email => current_publisher.user.email,
:period => 'Month',
:frequency => 1,
:cycles => #chosen_package.duration.to_i,
:start_date => Time.now.to_date,
:description => "Try to pay only #chosen_package.duration times !? "})
My comprehension is that the 'cycles' parameters should reflect as a maximum number of charge in sandbox test site but I'm stuck... like like it's not working !?
Any help appreciated ! Thx a lot !
Serge
I have found it by digging into ActiveMerchant source... The good parameters name is :total_billing_cycles, not :cycles as stated in the documentation that I have...
Work like a charm now :-)

How do I insert X-PAYPAL headers with Rails Invoice SDK?

I'm using the paypal SDK for invoicing located here:
https://github.com/paypal/invoice-sdk-ruby
This works great.
I integrated the paypal permissions SDK for rails:
https://github.com/paypal/permissions-sdk-ruby
The authorization workflow is working great.
So now I need to put them together. The documentation for the permissions sdk leaves off after you get your token. It doesn't explain how to use it with the other paypal SDKs (at least not so I could understand :D ) The invoice sdk tells you to see the Auth sdk.
Paypal tells me:
# Third-party Auth headers
-H "X-PAYPAL-SECURITY-SUBJECT:<receiverEdress>" # Merchant's PayPal e-mail
-H "X-PAYPAL-AUTHENTICATION:<OAuthSig>" # Generated OAuth Signature
Don't know how to insert that. The request is generated here in my model:
#create_and_send_invoice = api.build_create_and_send_invoice(paypalized || default_api_value)
The data itself is assembled in the invoice model like so:
paypalized = {
:access_token => self.user.paypal_token,
:invoice => {
:merchantEmail => self.user.paypal_email || self.user.email,
:payerEmail => self.client.email,
:itemList => #itemlist,
:currencyCode => "USD",
:paymentTerms => "DueOnReceipt",
:invoiceDate => self.updated_at,
:number => self.name,
:note => self.description,
:merchantInfo => #businessinfo
# project / Invoice title?
} # end invoice
} # end paypalized
return paypalized
This implementation is not working and the access_token field is being rejected. I looked through the gems associated with the sdks but can't see where the headers themselves are built or how to interact with that.
UPDATE: Found this which gives me a clue...
INVOICE_HTTP_HEADER = { "X-PAYPAL-REQUEST-SOURCE" => "invoice-ruby-sdk-#{VERSION}" }
This seems to be used here during calls in the paypal-sdk-invoice gem:
# Service Call: CreateAndSendInvoice
# #param CreateAndSendInvoiceRequest
# #return CreateAndSendInvoiceResponse
def CreateAndSendInvoice(options = {} , http_header = {})
request_object = BuildCreateAndSendInvoice(options)
request_hash = request_object.to_hash
...
I notice that there's two arguments: options and http_header. It's possible I can modify the http_header argument and pass it this way in my controller:
#create_and_send_invoice_response = api.create_and_send_invoice(#create_and_send_invoice, #cutsom_header)
or maybe
#create_and_send_invoice = api.build_create_and_send_invoice(data, custom_header)
I'll keep this updated since I googled around a lot and couldn't find any clear answers on how to do this...
You have to pass the token and token_secret while creating API object for third-party authentication.
#api = PayPal::SDK::Invoice::API.new({
:token => "replace with token",
:token_secret => "replace with token-secret" })

ActiveRecord Include, how to use in nested records?

I currently have the following:
#threads = current_user.threads.includes(:user, :thread_members)
I then take threads and do the following:
#threads.each do |thread|
thread_members = thread.thread_members_active(current_user)
#threadList << {
:id => thread.id,
:uuid => thread.uuid,
:user_id => thread.user.id,
:last_activity_at => thread.last_activity_at,
:user_count => thread_members.length,
:user_photos => thread_members.collect { |thread_member|
{
:id => thread_member.user.id,
:photo => thread_member.user.photo(:thumb),
:name => thread_member.user.full_name
}
},
:caption => thread.caption
}
end
The issue here is that every EACH loop, rails is hitting the DB for the same basic records. Rails sees to be caching as I see CACHE in the log but it's mighty messy. Leaves me wishing I could do some type of includes so there wasn't so many db requests.
Any ideas on how this can be optimized? Something around including all the users in one db hit?
Thanks
If you don't want any DB queries in the loop, you have to define everything that's used there in the named associations that are included, so instead of a thread_members_active method you'd define a thread_members_active association which has the same behavior. Note that the association also needs to use includes on user. Can't give you more right now, but maybe that helps a bit.
Edit: Check out the "Eager loading of associations" part of this doc:
http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

Resources