Sum of All Amount If Charge Dates Are the Same in Stripe

Sum of all amount if charge dates are the same in Stripe

You'll need to iterate through each charge object in Stripe, storing the amount and the parsed date for each charge:

# Fetch charges in batches of 100 records from Stripe API, yield each individual charge to a block.
def each_stripe_charge_for_customer(customer_id)
starting_after = nil
loop do
customer_charges = Stripe::Charge.all(customer: customer_id, limit: 100, starting_after: starting_after)
break if customer_charges.none?
charges.each do |charge|
yield charge
end
starting_after = charges.data.last.id
end
end

charges_by_date = Hash.new(0)

# For each Stripe charge, store the date and amount into a hash.
each_stripe_charge_for_customer(current_user.stripeid) do |stripe_charge|
# Parses Stripe's timestamp to a Ruby date object. `to_date` converts a DateTime object to a date (daily resolution).
charge_date = Time.at(stripe_charge.created).to_date
charge_amount = stripe_charge.amount

charges_by_date[charge_date] += charge_amount
end

Sum of all amount if created_at dates are the same in Rails

It looks like f is stored as a Hash object by calling as_json, yet you're treating it like a plain-old Ruby object in your each_user_foo block by using the . operator.

The solution is to use the hash accessor operator instead (eg f[:created_at]). You also don't need to stringify and parse the date because it's already a DateTime object:

amount_date = f[:created_at].to_date # line 50
amount = f[:amount]

Also, Foo is a model class right? If so, I'd recommend using pluck to get the attributes you need, which will be more efficient and cleaner than calling as_json:

# As per first link above
def each_user_foo
f = Foo.where(client_id: 4).pluck(:created_at, :amount)
f.each do |bar|
yield(bar.first, bar.last)
end
end

foo_by_date = Hash.new(0)

each_user_foo do |created_at, amount|
# Parses date object. `to_date` converts a DateTime object to a date (daily resolution).
amount_date = created_at.to_date # line 50
foo_by_date[amount_date] += amount
end

You can remove this line as well:

foo_by_date[amount_date] ||= 0 

Since you're using an initializer in your foo_by_date = Hash.new(0) variable assignment).

EDIT

If you're using Postgres, just do:

Foo.where(client_id: 4).group("date_trunc('day', created_at)").sum(:amount)

Or for MySQL:

Foo.where(client_id: 4).group("DAY(created_at)").sum(:amount)

Much, much simpler than your current approach.

The equivalent of console.log() in Rails is Rails.logger.info(), you can also use Rails.logger.warn() and Rails.logger.error(). Really, any function that outputs to STDOUT, such as puts and print will output to your console.

Represent Stripe Charge Amount and Date with Chart.js

I don't think you want to do all this date processing in Javascript. Let Ruby/Rails do the heavy lifting for you.

Suppose you have a method that maps charges to a date, where each key in the hash is a day and the value is a count:

def each_stripe_charge_for_customer(customer_id, created)
starting_after = nil
loop do
customer_charges = Stripe::Charge.all customer: customer_id,
created: created,
limit: 100,
starting_after: starting_after
break if customer_charges.none?
customer_charges.each do |charge|
yield charge
end
starting_after = customer_charges.data.last.id
end
end

def daily_charges_for_customer(customer_id, created=nil)
charges_by_date = Hash.new(0)

# For each Stripe charge, store the date and amount into a hash.
each_stripe_charge_for_customer(customer_id, created) do |stripe_charge|
# Parses Stripe's timestamp to a Ruby date object. `to_date` converts a DateTime object to a date (daily resolution).
charge_date = Time.at(stripe_charge.created).to_date
charge_amount = stripe_charge.amount

charges_by_date[charge_date] += charge_amount
end

charges_by_date
end

So now, daily_charges_for_customer(customer_id, 1.week.ago.to_i) returns something like:

{
'19 Jan' => 10,
'20 Jan' => 20
}

You should cache this result whenever possible so you're not constantly hitting the Stripe API

Now, you can pass this as a data-attribute within the DOM:

In your view:

<%= content_tag :canvas, "", id: "myChart", width: "400", height: "200", data: { charges: daily_charges_for_customer(customer_id, 1.week.ago.to_i) } %>

This will simplify your javascript considerably:

In your JS code:

var ctx = $("#moneyHistory");

var cumulative_daily_charges = ctx.data("charges");
var date_labels = Object.keys(cumulative_daily_charges);
var daily_charges = date_labels.map(function(v) { return cumulative_daily_charges[v]; });

var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: date_labels,
datasets: [{
label: 'Date',
data: daily_charges
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});

I'm writing this sort of "off the cuff" so you may need to fix some typos/syntax errors, but the logic and major nuts-and-bolts should work. Let me know if you run into any issues.

EDIT

Also, I don't think amount.sort() and d.sort() will act as you expect them to. If they're separate arrays, they'll be sorted independently.

Listing Stripe refunds between dates

I would use the List All Balance History API and pass type: "refund" to only list the refunds and also pass the created hash based on the dates I want to limit my search to and you should get all the balance transactions associated with a refund created between those two dates.

Is it possible to alter a recurring price that an existing customer is charged with Stripe API?

You would want to think Subscription as per-customer object. Let's say you have 100 existing Customers already subscribed to a $10 monthly plan, there are 100 existing Subscriptions object, tights to each of those Customers.

Now if the Connected Account created a new price of $12/month, all new Customers will subscribe to this new price, and create separated new Subscription objects.

If you want to upgrade the currently existing Subscriptions, you would need to update each of them, changing the old price to the new price, by Stripe's Subscription Update API. Make sure to read the note about Proration, or refer to Proration Doc

How to get charges(transactions) details in Stripe based on date range

Had a chat with Stripe staffs through online chat, and found that there is a way to get list of charges based on date range.

Stripe Charges API actually has some argument that are not yet listed in their documentation.

Arguments like created[lte] and created[gte] with Unix timestamp can be used, just like Events API call.

EG: https://api.stripe.com/v1/charges?created[gte]=1362171974&created[lte]=1362517574

Stripe immediate payment on each quantity update

To charge immediately after subscription update, you need to create an invoice just after the subscription update. This will result in an immediate charge

To create invoice you can simply call:

Stripe.apiKey = "sk_test_BQokikJOvBiI2HlWgH4UWQfQ2";

Map<String, Object> invoiceParams = new HashMap<String, Object>();
invoiceParams.put("customer", "cus_D2XUIsncG7YUX");

Invoice.create(invoiceParams);

Ref (https://stripe.com/docs/api#update_subscription):

Sample Image

Rails 3: Instance variable not working as charge amount for Stripe?

Im not sure because I cannot see your model code but I suspect this is because you have no attr_accessor set for :total, so attr_accessor :total in the modal and see what happens. unless i have a better idea (see your code) about how your payment process is structured I cant really give a solid answer on the matter. By you can check out http://railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby/ to see if you find something that works for you.

EDIT

I though you were talking about model instance variable, you have to pass the instance variable from the controller to the model. Below is an example.

Controller snippet

...
@video.save if @video.all_valid? && @video.save_with_payment(@total)
...

Model snippet

...
def save_with_payment(total)
if valid?
charge = Stripe::Charge.create(
amount: total,
currency: "usd",
card: stripe_card_token
)
end


Related Topics



Leave a reply



Submit