I setup my shop with Stripe. You can buy it with the good product and with different sizes. It works well until I have to sent an email to the seller with some informations like the name of the product bought, the size of the product (product.nickname), the customer information and so on. My problem is I can't get this 'nickname'.
As I understand in Stripe, you have some Products, which can have different Prices. For me, I have a product with 3 prices. Each price has his own ID and a 'label' (according to Stripe called 'nickname' as I saw in the request). The problem came when I want to retrieve this ID to get the specific nickname (the name if the size). For some reason, the ID returned for the selected product is not the same as the ID from Stripe Dashboard. And each time I got a new purchase, this returned ID change.
In my WebhooksController in def create:
case event.type
when 'checkout.session.completed'
session = event.data.object
#order = Stripe::Checkout::Session.retrieve({ id: session.id, expand: ["line_items", "customer"]})
OrderMailer.order_mail(#order).deliver
end
render json: { message: 'success' }
In my order_mail.html.erb:
<% #order.line_items.data.each do |line| %>
<%= line %>
<% end %>
Can someone explain me why the line_item ID returned in the webhook is not the same as the Stripe dashboard ID? And how can I get and display the nickname of the price selected in my mail?
here is what I got for the <%= line %>
{ "id": "li_1K41JPFE4oPSz5YO98K2r2CW", "object": "item", "amount_subtotal": 4000, "amount_total": 4000, "currency": "eur", "description": "Soleil Levant", "price": { "id": "price_1K41JPFE4oPSz5YORWdXXGuT", "object": "price", "active": false, "billing_scheme": "per_unit", "created": 1638874459, "currency": "eur", "livemode": false, "lookup_key": null, "metadata": { }, "nickname": null, "product": "prod_KjUHP8uALE6aZI", "recurring": null, "tax_behavior": "unspecified", "tiers_mode": null, "transform_quantity": null, "type": "one_time", "unit_amount": 4000, "unit_amount_decimal": "4000" }, "quantity": 1 }
If I cUrl the right price:
https://api.stripe.com/v1/prices/price_1JxC8kFE4oPSz5YOc391IZ9I\
-u sk_test_51JbmGvFE4oPSz5YOsl0JTTEi0quapEwPBXQsQRbRXPdr38hSiyVDPs9LnkH4nHCGXqwoYjOTnHoH6FtIC4EP32pr00KHIxFlLp:
I got this:
{
"id": "price_1JxC8kFE4oPSz5YOc391IZ9I",
"object": "price",
"active": true,
"billing_scheme": "per_unit",
"created": 1637247786,
"currency": "eur",
"livemode": false,
"lookup_key": null,
"metadata": {
"nickname": "S"
},
"nickname": "S",
"product": "prod_KcR0HgpfzldOj8",
"recurring": null,
"tax_behavior": "unspecified",
"tiers_mode": null,
"transform_quantity": null,
"type": "one_time",
"unit_amount": 4000,
"unit_amount_decimal": "4000"
}
What you are doing should work:
First, create a Price with nickname: "foobar", let’s say its ID is "price_abc".
Then, create a Checkout Session where you set line_items[0].price: "price_abc".
Later, you retrieve the Checkout Session with expand: ["line_items"]. If you look into checkout.line_items.data[].price, you will find an object that contains what you are looking for: { id: "price_abc", nickname: "foobar", … }. Note that you can see the structure of the line_items.data object in the Stripe documentation here.
So you need to double check that you are using the correct price ID when creating the Checkout Session, and that you are looking at checkout.line_items.data[].price to find the id and nickname of the price.
Related
I'm building a REST API in Elixir/Phoenix and documenting the endpoints via Phoenix Swagger.
I have an entity called users which has the following code inside swagger_definitions in user_controller.ex
def swagger_definitions do
%{
User:
swagger_schema do
title("User")
description("A user in the application")
properties do
first_name(:string, "First name")
last_name(:string, "Last name")
email(:string, "Email")
role(:string, "User role")
end
example(%{
first_name: "Rahul",
last_name: "Sharma",
email: "rahul.sharma#example.com",
role: "student"
})
end,
Users:
swagger_schema do
title("Users")
description("All users in the application")
type(:array)
items(Schema.ref(:User))
end,
}
end
Now, there's another controller session_controller.ex which returns the many-to-many related users to a session when calling the single session GET endpoint. Here's an example of the response:
{
"end_time": "2022-02-02T11:30:00Z",
"id": 1,
"start_time": "2022-02-02T11:00:00Z",
"users": [
{
"email": "janedoe#example.com",
"first_name": "Jane",
"id": 1,
"last_name": "Doe",
"role": null,
},
{
"email": "johndoe#example.com",
"first_name": "John",
"id": 2,
"last_name": "Doe",
"role": null,
}
]
}
Now, when I'm trying to document the above API response using the Swagger example within session_controller.ex, the example isn't coming up correctly in Swagger UI:
SessionWithUser:
swagger_schema do
title("SessionWithUser")
properties do
session_id(:integer, "Session ID")
start_time(:timestamp, "Session start time")
end_time(:timestamp, "Session finish time")
users(Schema.ref(:Users), "Users attending the session")
end
example(%{
session_id: 1,
start_time: "2022-02-02T11:00:00Z",
end_time: "2022-02-02T11:30:00Z",
users: Schema.items(:User)
})
end
What am I doing wrong?
I am creating a setup intent and receiving the payment method's id from it. Then I am creating a customer using the following code
customer = Stripe::Customer.create({
email: current_user.email,
description: "Customer for subscription",
payment_method: params[:payment_method]
})
It is returning the following response
{
"id": "cus_IZmhg4VhIwFUBI",
"object": "customer",
"address": null,
"balance": 0,
"created": 1608037176,
"currency": null,
"default_source": null,
"delinquent": false,
"description": "Customer for subscription",
"discount": null,
"email": "customer#example.com",
"invoice_prefix": "76BF0C5E",
"invoice_settings": {
"custom_fields": null,
"default_payment_method": null,
"footer": null
},
"livemode": false,
"metadata": {
},
"name": null,
"next_invoice_sequence": 1,
"phone": null,
"preferred_locales": [
],
"shipping": null,
"tax_exempt": "none"
}
The problem is, it is not attaching the payment method to the customer, when I try to create a subscription using the customer object, it returns the following error:
Stripe::InvalidRequestError (This customer has no attached payment source or default payment method.):
But when I look in the dashboard, the payment method is already attached with the customer
The payment_method is attached, and you can list them for the customer. Then, you need to set explicitly the invoice_settings.default_payment_method for the Customer, which is what will be used for the subscription creation.
Inspired by the #Nolan's answer, I have fixed the issue by passing payment id to invoice_settings.default_payment_method while customer creation. Following is the code snippet:
customer = Stripe::Customer.create({
email: current_user.email,
description: "Customer for subscription",
payment_method: params[:payment_method],
invoice_settings: {
default_payment_method: params[:payment_method]
}
})
I am trying to design an appointment schedule layed out by week in my react on rails application. It should look like this when done:
Colored boxes will be bootstrap classes depending on the status of the appointment. They should be links to the individual appointment show pages (I know I don't have this done yet, it's not my primary concern at the moment).
Here is the data structure I'm working with in JSON:
{
"clients": [
{
"id": 2,
"name": "Oscar",
"appointments": [
{
"id": 2,
"status": "Not Done",
"report": "Not Started",
"start": "2017-09-24T12:06:19.000Z",
"finish": "2017-09-24T12:36:19.000Z",
"scheduled": "2017-09-24T12:09:19.000Z",
"duration": null
},
{
"id": 3,
"status": "Not Done",
"report": "Not Started",
"start": "2017-09-18T13:07:56.000Z",
"finish": "2017-09-18T13:37:56.000Z",
"scheduled": "2017-09-18T13:10:56.000Z",
"duration": null
}
],
"url": "http:\/\/localhost:3000\/clients\/2.json"
},
{
"id": 3,
"name": "Molly",
"appointments": [
{
"id": 4,
"status": "Not Done",
"report": "Not Started",
"start": "2017-09-21T11:09:31.000Z",
"finish": "2017-09-21T11:39:31.000Z",
"scheduled": "2017-09-21T11:12:31.000Z",
"duration": null
}
],
"url": "http:\/\/localhost:3000\/clients\/3.json"
}]}
Appointments.js.coffee
#Appointments = React.createClass
getInitialState: ->
clients: #props.clients
getDefaultProps: ->
clients: []
render: ->
React.DOM.div
className: 'client-appts'
React.DOM.h2
className: 'title'
'Clients Title'
React.DOM.table
className: 'table table-bordered'
React.DOM.thead null,
React.DOM.tr null,
React.DOM.th null, 'Client'
React.DOM.th null, 'col 2'
React.DOM.th null, 'col 3'
React.DOM.tbody null,
for client in #state.Clients
React.createElement Client, key: client.id, client: client
This is my client.js.coffee
#Client= React.createClass
render: ->
React.DOM.tr null,
React.DOM.td null, #props.client.name
for appointment in #props.client.appointments
React.createElement Appointment, key: appointment.id, appointment: appointment
This is my appointment.js.coffee
#Appointment = React.createClass
render: ->
React.DOM.td null,
React.DOM.p null, #props.appointment.status
React.DOM.p null, #props.appointment.report
I know rails OK, but am new to react. How do I design the structure so that the appointments show up only when they're supposed to. Once I have that figured out I need to figure out how to click through pages for different weeks. How do I design the react components? Anyone see another good example on S/O or G/H?
I browse around PayPal's API and I was not able to find the information I am looking for. I would like to save the billing period end value for the new subscription to the database. I have two plans to choose from, monthly and annually. Each subscription plan is set to auto renewal.
If someone could help assist me in saving the end date of the billing period to the Subscriptions table that would be helpful!
I need help finding the PayPal attribute I can call on to save to the database since I can't locate it in the API.
Legal note: This answer is based on my understanding, you should verify anything you have a question on with PayPal. Your reading and use of any information contained herein constitutes your agreement that any liability on my part for your use of this information is limited to $1 including all types of claims, special, etc.
If you do, or will continue to, receive end date information is unclear. The existence of a final_payment_date property is not defined in the PayPal API specification. However, in one, and only one of multiple examples, an additional agreement_details object is shown. This object is not mentioned anywhere else in the API specification other than within the "Response Sample" provided as an example of the response to a request to "Retrieve an agreement". Nor are any of the properties anywhere else in the API specification, other than in that one example.
The example shows this object as:
"agreement_details": {
"outstanding_balance": {
"currency": "USD",
"value": "0.00"
},
"cycles_remaining": "12",
"cycles_completed": "0",
"final_payment_date": "2016-12-19T10:00:00Z",
"failed_payment_count": "0"
}
As can be noted this structure contains very useful information, some of which is unavailable elsewhere. It is possible, even probable that this structure was merely left out of the specification by accident. However, there is no way to know that for sure. You will need to make a choice as to how you want to handle the situation.
If I were writing code to interact with the API: If the code was just for my own use, I would go ahead an use/rely on the structure and make some effort to contact PayPal for clarification. If I were writing code to be used for any other situation other than myself, I would make a very concerted effort to get clarification from PayPal. If I received no clarification from PayPal, I would probably have the code calculate the end date and compare it against the date which might be in this field. At a minimum, I would log a warning/bring it to the user's attention if there was a discrepancy.
It should be noted that this information is not contained in the examples of the responses you get when going through the process of "Create an agreement", "Execute an agreement", "Update an agreement", "Suspend an agreement", "Reactivate an agreement", "Cancel an agreement", "Set outstanding agreement amounts", or "Bill outstanding agreement amounts".
The full example of the response to a "Retrieve an agreement" request is:
{
"id": "I-0LN988D3JACS",
"state": "Pending",
"description": "New Description",
"plan": {
"payment_definitions": [
{
"type": "REGULAR",
"frequency": "Month",
"amount": {
"currency": "USD",
"value": "100.00"
},
"charge_models": [
{
"type": "TAX",
"amount": {
"currency": "USD",
"value": "12.00"
}
},
{
"type": "SHIPPING",
"amount": {
"currency": "USD",
"value": "10.00"
}
}
],
"cycles": "12",
"frequency_interval": "2"
}
],
"merchant_preferences": {
"setup_fee": {
"currency": "USD",
"value": "0.00"
},
"max_fail_attempts": "0",
"auto_bill_amount": "YES"
}
},
"links": [
{
"href": "https://api.sandbox.paypal.com/v1/payments/billing-agreements/I-0LN988D3JACS/suspend",
"rel": "suspend",
"method": "POST"
},
{
"href": "https://api.sandbox.paypal.com/v1/payments/billing-agreements/I-0LN988D3JACS/re-activate",
"rel": "re_activate",
"method": "POST"
},
{
"href": "https://api.sandbox.paypal.com/v1/payments/billing-agreements/I-0LN988D3JACS/cancel",
"rel": "cancel",
"method": "POST"
},
{
"href": "https://api.sandbox.paypal.com/v1/payments/billing-agreements/I-0LN988D3JACS/bill-balance",
"rel": "self",
"method": "POST"
},
{
"href": "https://api.sandbox.paypal.com/v1/payments/billing-agreements/I-0LN988D3JACS/set-balance",
"rel": "self",
"method": "POST"
}
],
"start_date": "2015-02-19T08:00:00Z",
"agreement_details": {
"outstanding_balance": {
"currency": "USD",
"value": "0.00"
},
"cycles_remaining": "12",
"cycles_completed": "0",
"final_payment_date": "2016-12-19T10:00:00Z",
"failed_payment_count": "0"
}
}
The PayPal API specifies that "After creating a profile, PayPal automatically queues payments based on the billing start date, billing frequency, and billing amount. Payments reoccur until the profile expires, there are too many failed payments to continue, or you cancel the profile." Thus, the end date is based on the start date and billing frequency, and number of payments.
In contrast to the above data structure, when you "Create an agreement", the request returns no calculated information as to the end date. The data you receive as a response looks like:
Response (agreement object):
Returns the agreement object based on the billing plan. The response includes a billing agreement id and return links to obtain the buyer information and to execute the subscription.
Property Type Description
id string Identifier of the agreement.
name string Name of the agreement.
description string Description of the agreement.
start_date string Start date of the agreement. Date format yyyy-MM-dd z, as defined in ISO8601.
payer payer Details of the buyer who is enrolling in this agreement. This information is gathered from execution of the approval URL.
shipping_address address Shipping address object of the agreement, which should be provided if it is different from the default address.
override_merchant_preferences merchant_preferences Default merchant preferences from the billing plan are used, unless override preferences are provided here.
override_charge_models array of override_charge_model Array of override_charge_model for this agreement if needed to change the default models from the billing plan.
plan plan Plan details for this agreement.
create_time string Date and time that this resource was created. Date format yyyy-MM-dd z, as defined in ISO8601.
update_time string Date and time that this resource was updated. Date format yyyy-MM-dd z, as defined in ISO8601.
links array of links ~
plan object:
Billing plan resource that will be used to create a billing agreement.
Property Type Description
id string Identifier of the billing plan. Assigned in response.
name string Name of the billing plan. Required.
description string Description of the billing plan. Required.
type string Type of the billing plan. Possible types include: FIXED and INFINITE. Required.
state string Status of the billing plan. Possible states include: CREATED, ACTIVE, and INACTIVE. Assigned in response.
payee payee Details of the merchant who is creating this billing plan. Assigned in response.
create_time string Time when the billing plan was created, represented as YYYY-MM-DDTimeTimezone format. Assigned in response.
update_time string Time when this billing plan was updated, represented as YYYY-MM-DDTimeTimezone format. Assigned in response.
payment_definitions array of payment_definition Array of payment definitions for this billing plan.
terms array of terms Array of terms for this billing plan. Assigned in response.
merchant_preferences merchant_preferences Specific preferences such as: set up fee, max fail attempts, autobill amount, and others that are configured for this billing plan.
links array of links ~
payment_definition object:
Resource representing payment definition scheduling information.
Property Type Description
id string Identifier of the payment_definition. Assigned in response.
name string Name of the payment definition. Required.
type string Type of the payment definition. Possible types include: TRIAL and REGULAR. Required.
frequency_interval string How frequently the customer should be charged. Required.
frequency string Frequency of the payment definition offered. Required.
cycles string Number of cycles in this payment definition. Required.
amount currency Amount that will be charged at the end of each cycle for this payment definition. Required.
charge_models array of charge_models Array of charge_models for this payment definition.
terms object:
Resource representing terms used by the plan.
Property Type Description
id string Identifier of the terms. Assigned in response.
type string Term type Required.
max_billing_amount currency Max Amount associated with this term. Required.
occurrences string How many times money can be pulled during this term. Required.
amount_range currency Amount_range associated with this term. Required.
buyer_editable string Buyer’s ability to edit the amount in this term. Required.
currency object:
Base object for all financial value related fields (balance, payment due, etc.)
Property Type Description
currency string 3 letter currency code as defined by ISO 4217. Required.
value string amount up to N digit after the decimals separator as defined in ISO 4217 for the appropriate currency code. Required.
charge_models object:
A resource representing a charge model for a payment definition.
Property Type Description
id string Identifier of the charge model. Assigned in response.
type string Type of charge model, possible values can be shipping/tax. Required.
amount currency Specific amount for this charge model. Required.
[Some portions of the data structure definition are not included here as they do not affect the end date.]
Example response:
{
"name": "T-Shirt of the Month Club Agreement",
"description": "Agreement for T-Shirt of the Month Club Plan",
"plan": {
"id": "P-94458432VR012762KRWBZEUA",
"state": "ACTIVE",
"name": "T-Shirt of the Month Club Plan",
"description": "Template creation.",
"type": "FIXED",
"payment_definitions": [
{
"id": "PD-50606817NF8063316RWBZEUA",
"name": "Regular Payments",
"type": "REGULAR",
"frequency": "Month",
"amount": {
"currency": "USD",
"value": "100"
},
"charge_models": [
{
"id": "CHM-92S85978TN737850VRWBZEUA",
"type": "TAX",
"amount": {
"currency": "USD",
"value": "12"
}
},
{
"id": "CHM-55M5618301871492MRWBZEUA",
"type": "SHIPPING",
"amount": {
"currency": "USD",
"value": "10"
}
}
],
"cycles": "12",
"frequency_interval": "2"
}
],
"merchant_preferences": {
"setup_fee": {
"currency": "USD",
"value": "1"
},
"max_fail_attempts": "0",
"return_url": "http://www.return.com",
"cancel_url": "http://www.cancel.com",
"auto_bill_amount": "YES",
"initial_fail_amount_action": "CONTINUE"
}
},
"links": [
{
"href": "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-0JP008296V451950C",
"rel": "approval_url",
"method": "REDIRECT"
},
{
"href": "https://api.sandbox.paypal.com/v1/payments/billing-agreements/EC-0JP008296V451950C/agreement-execute",
"rel": "execute",
"method": "POST"
}
],
"start_date": "2015-02-19T00:37:04Z"
}
Calculating the end date yourself:
For this profile the information relevant to determining the end date is:
{
"plan": {
"payment_definitions": [
{
"frequency": "Month",
"cycles": "12",
"frequency_interval": "2"
}
],
},
"start_date": "2015-02-19T00:37:04Z"
}
That is the information you receive. You do not get an explicitly stated end date. You have to calculate the end of the payments yourself. In the above example, payments would be made 12 times, every other month, starting on 2015-02-19. The customer will be billed on the following days:
Charge Date
Number
1 2015-02-19
2 2015-04-19
3 2015-06-19
4 2015-08-19
5 2015-10-19
6 2015-12-19
7 2016-02-19
8 2016-04-19
9 2016-06-19
10 2016-08-19
11 2016-10-19
12 2016-12-19
Once you retrieve the Billing Agreement Details you will get the variable "final_payment_date" which you can store in your DB as it indicates the end date for the billing agreement .
I have included the sample request and response :
Request
GET https://api.sandbox.paypal.com/v1/payments/billing-agreements/I-YBM89E79APJ1
Response :
{
"id": "I-YBM89E79APJ1",
"state": "Active",
"description": "Agreement for Fast Speed Plan",
"plan": {
"payment_definitions": [
{
"type": "TRIAL",
"frequency": "Month",
"amount": {
"currency": "USD",
"value": "100.00"
},
"cycles": "12",
"charge_models": [
{
"type": "TAX",
"amount": {
"currency": "USD",
"value": "12.00"
}
},
{
"type": "SHIPPING",
"amount": {
"currency": "USD",
"value": "10.00"
}
}
],
"frequency_interval": "2"
},
{
"type": "REGULAR",
"frequency": "Month",
"amount": {
"currency": "USD",
"value": "100.00"
},
"cycles": "12",
"charge_models": [
{
"type": "TAX",
"amount": {
"currency": "USD",
"value": "12.00"
}
},
{
"type": "SHIPPING",
"amount": {
"currency": "USD",
"value": "10.00"
}
}
],
"frequency_interval": "2"
}
],
"merchant_preferences": {
"setup_fee": {
"currency": "USD",
"value": "1.00"
},
"max_fail_attempts": "0",
"auto_bill_amount": "YES"
}
},
"links": [
{
"href": "https://api.sandbox.paypal.com/v1/payments/billing-agreements/I-YBM89E79APJ1/suspend",
"rel": "suspend",
"method": "POST"
},
{
"href": "https://api.sandbox.paypal.com/v1/payments/billing-agreements/I-YBM89E79APJ1/re-activate",
"rel": "re_activate",
"method": "POST"
},
{
"href": "https://api.sandbox.paypal.com/v1/payments/billing-agreements/I-YBM89E79APJ1/cancel",
"rel": "cancel",
"method": "POST"
},
{
"href": "https://api.sandbox.paypal.com/v1/payments/billing-agreements/I-YBM89E79APJ1/bill-balance",
"rel": "self",
"method": "POST"
},
{
"href": "https://api.sandbox.paypal.com/v1/payments/billing-agreements/I-YBM89E79APJ1/set-balance",
"rel": "self",
"method": "POST"
}
],
"start_date": "2015-02-19T08:00:00Z",
"agreement_details": {
"outstanding_balance": {
"currency": "USD",
"value": "0.00"
},
"cycles_remaining": "12",
"cycles_completed": "0",
"next_billing_date": "2015-02-19T08:00:00Z",
"last_payment_date": "2014-07-21T09:18:28Z",
"last_payment_amount": {
"currency": "USD",
"value": "1.00"
},
"final_payment_date": "2018-12-19T10:00:00Z",
"failed_payment_count": "0"
}
}
I am trying to save the Stripe's user current_period_end to the database. When I create a new subscription the value saves as 0 instead of the actual date their subscription ends.
Is there something I'm missing?
It should be saving as:
"current_period_end": 1441292360
Subscription.rb:
def save_with_stripe_payment
customer = Stripe::Customer.create(description: email, plan: plan_id, card: stripe_card_token)
self.stripe_customer_token = customer.id
self.cancellation_date = customer.subscriptions.first.current_period_end
save!
rescue Stripe::InvalidRequestError => e
logger.error "Stripe error while creating customer: #{e.message}"
errors.add :base, "There was a problem with your credit card."
false
end
It's possible that this could be an issue with the type of data you're receiving and how you're storing it in your database. Based on the information you have given I would expect you have the wrong field type.
Your code is correct so I would double check to see if your field is a integer.
When Strip creates a new customer it returns the object posted at the bottom of this question.
To access the current_period_end you would need to do customer.subscriptions.data.first["current_period_end"]
{
"object": "customer",
"created": 1409190039,
"id": "cus_4fdAW5ftNQow1a",
"livemode": false,
"description": "new_paying_customer",
"email": null,
"delinquent": false,
"metadata": {},
"subscriptions": {
"object": "list",
"total_count": 1,
"has_more": false,
"url": "/v1/customers/cus_4fdAW5ftNQow1a/subscriptions",
"data": [
{
"id": "sub_4fdAS9IlSOFfiv",
"plan": {
"interval": "month",
"name": "Basic Plan",
"created": 1409178429,
"amount": 1200,
"currency": "usd",
"id": "basic",
"object": "plan",
"livemode": false,
"interval_count": 1,
"trial_period_days": null,
"metadata": {},
"statement_description": null
},
"object": "subscription",
"start": 1409190039,
"status": "active",
"customer": "cus_4fdAW5ftNQow1a",
"cancel_at_period_end": false,
"current_period_start": 1409190039,
"current_period_end": 1411868439,
"ended_at": null,
"trial_start": null,
"trial_end": null,
"canceled_at": null,
"quantity": 1,
"application_fee_percent": null,
"discount": null,
"metadata": {}
}
]
},
"discount": null,
"account_balance": 0,
"currency": "usd",
"cards": {
"object": "list",
"total_count": 1,
"has_more": false,
"url": "/v1/customers/cus_4fdAW5ftNQow1a/cards",
"data": [
{
"id": "card_14WHtz4rPA98z9GRTW1QMenU",
"object": "card",
"last4": "4242",
"brand": "Visa",
"funding": "unknown",
"exp_month": 1,
"exp_year": 2015,
"fingerprint": "0qYXzA0d9EZtsgQ6",
"customer": "cus_4fdAW5ftNQow1a"
}
]
},
"default_card": "card_14WHtz4rPA98z9GRTW1QMenU"
}
This is just a shot in the dark (because I don't know the format of your cancellation_date field or the database you are using), but are you sure you are handling the returned timestamp correctly?
If cancellation_date is a DateTime field, I believe you have to do something like:
cpe = customer.subscriptions.first.current_period_end
self.cancellation_date = Time.at(cpe).to_datetime
If that isn't the problem then I'd use the console and/or the server output to make sure current_period_end is returning what you expect it to when you call Stripe::Customer.create (like others have suggested). You really need to determine when the "switch to 0" is happening, so I'd check (in this order):
The response from Stripe when you create the customer
The value of customer.subscriptions.first.current_period_end
The value of self.cancellation_date after assignment but before saving
There may also be validations or before_save filters that are messing with this field before hitting the database.
That's all my ideas for now :)
Hope this helps!