Skip to content
Browse files

Ability to Create a customer using Card Token, Issue #1

  • Loading branch information...
1 parent 5320e94 commit 212128161d19a3d9ab950d52e370d5360ac5e41a @bradrydzewski committed
Showing with 81 additions and 80 deletions.
  1. +0 −2 charge.go
  2. +44 −69 customer.go
  3. +37 −9 customer_test.go
View
2 charge.go
@@ -76,7 +76,6 @@ type ChargeParams struct {
// querying charges using the Stripe REST API.
type ChargeClient struct{}
-
// Creates a new credit card Charge.
//
// see https://stripe.com/docs/api#create_charge
@@ -164,7 +163,6 @@ func (self *ChargeClient) CustomerListN(id string, count int, offset int) ([]*Ch
return self.list(id, count, offset)
}
-
func (self *ChargeClient) list(id string, count int, offset int) ([]*Charge, error) {
// define a wrapper function for the Charge List, so that we can
// cleanly parse the JSON
View
113 customer.go
@@ -5,41 +5,20 @@ import (
"strconv"
)
-// Customer object
+// Customer encapsulates details about a Customer registered in Stripe.
//
// see https://stripe.com/docs/api#customer_object
type Customer struct {
- // Customer's Unique Identifier within the Stripe database.
- Id string `json:"id"`
- Desc string `json:"description,omitempty"`
-
- // Customer's Email address
- Email string `json:"email,omitempty"`
- Created int64 `json:"created"`
-
- // Current balance, if any, being stored on the customer's account. If
- // negative, the customer has credit to apply to the next invoice. If
- // positive, the customer has an amount owed that will be added to the next
- // invoice. The balance does not refer to any unpaid invoices; it solely
- // takes into account amounts that have yet to be successfully applied to
- // any invoice.
- Balance int64 `json:"account_balance"`
-
- // Whether or not the latest charge for the customer's latest invoice has
- // failed.
- Delinquent bool `json:"delinquent"`
-
- // Describes the active credit card for the customer, if there is one.
- Card *Card `json:"active_card,omitempty"`
-
- // Describes the current discount active for the customer, if there is one.
- Discount *Discount `json:"discount,omitempty"`
-
- // Describes the current subscription for the customer, if there is one. If
- // the customer has no current subscription, this will be null.
+ Id string `json:"id"`
+ Desc String `json:"description,omitempty"`
+ Email String `json:"email,omitempty"`
+ Created int64 `json:"created"`
+ Balance int64 `json:"account_balance"`
+ Delinquent bool `json:"delinquent"`
+ Card *Card `json:"active_card,omitempty"`
+ Discount *Discount `json:"discount,omitempty"`
Subscription *Subscription `json:"subscription,omitempty"`
-
- Livemode bool `json:"livemode"`
+ Livemode bool `json:"livemode"`
}
// Discount represents the actual application of a coupon to a particular
@@ -47,54 +26,46 @@ type Customer struct {
//
// see https://stripe.com/docs/api#discount_object
type Discount struct {
- // Discount's Unique Identifier within the Stripe database.
- Id string `json:"id"`
-
- // Customer's Unique Identifier that has received this discount.
- Customer string `json:"customer"`
-
- // Date that the coupon was applied
- Start Int64 `json:"start"`
-
- // If the coupon has a duration of once or multi-month, the date that this
- // discount will end. If the coupon used has a forever duration, this
- // attribute will be null.
- End Int64 `json:"end"`
-
- // the Coupon applied to create this discount
- Coupon *Coupon `json:"coupon"`
+ Id string `json:"id"`
+ Customer string `json:"customer"`
+ Start Int64 `json:"start"`
+ End Int64 `json:"end"`
+ Coupon *Coupon `json:"coupon"`
}
-// CustomerParams is a data structure that represents the required input
-// parameters for Creating and Updating Customer data in the system.
+// CustomerParams encapsulates options for creating and updating Customers.
type CustomerParams struct {
- Email, Desc string
+ // (Optional) The customer's email address.
+ Email string
- // Credit Card to attach to the customer.
+ // (Optional) An arbitrary string which you can attach to a customer object.
+ Desc string
+
+ // (Optional) Customer's Active Credit Card
Card *CardParams
- // If you provide a coupon code, the customer will have a discount applied
- // on all recurring charges.
+ // (Optional) Customer's Active Credid Card, using a Card Token
+ Token string
+
+ // (Optional) If you provide a coupon code, the customer will have a
+ // discount applied on all recurring charges.
Coupon string
- // The identifier of the plan to subscribe the customer to. If provided,
- // the returned customer object has a 'subscription' attribute describing
- // the state of the customer's subscription.
+ // (Optional) The identifier of the plan to subscribe the customer to. If
+ // provided, the returned customer object has a 'subscription' attribute
+ // describing the state of the customer's subscription.
Plan string
- // UTC integer timestamp representing the end of the trial period the
- // customer will get before being charged for the first time.
+ // (Optional) UTC integer timestamp representing the end of the trial period
+ // the customer will get before being charged for the first time.
TrialEnd int64
}
-// CustomerClient is a wrapper around the Stripe Customer API, allowing you to
-// perform recurring charges and track multiple charges that are associated with
-// the same customer. The API allows you to create, delete, and update your
-// customers. You can retrieve individual customers as well as a list of all
-// your customers.
+// CustomerClient encapsulates operations for creating, updating, deleting and
+// querying customers using the Stripe REST API.
type CustomerClient struct{}
-// Creates a new customer object.
+// Creates a new Customer.
//
// see https://stripe.com/docs/api#create_customer
func (self *CustomerClient) Create(c *CustomerParams) (*Customer, error) {
@@ -106,8 +77,7 @@ func (self *CustomerClient) Create(c *CustomerParams) (*Customer, error) {
return &customer, err
}
-// Retrieves the details of an existing customer using the provided customer
-// identifier.
+// Retrieves a Customer with the given ID.
//
// see https://stripe.com/docs/api#retrieve_customer
func (self *CustomerClient) Retrieve(id string) (*Customer, error) {
@@ -117,8 +87,7 @@ func (self *CustomerClient) Retrieve(id string) (*Customer, error) {
return &customer, err
}
-// Updates the specified customer by setting the values of the parameters
-// passed.
+// Updates a Customer with the given ID.
//
// see https://stripe.com/docs/api#update_customer
func (self *CustomerClient) Update(id string, c *CustomerParams) (*Customer, error) {
@@ -130,7 +99,7 @@ func (self *CustomerClient) Update(id string, c *CustomerParams) (*Customer, err
return &customer, err
}
-// Permanently deletes a customer. It cannot be undone.
+// Deletes a Customer (permanently) with the given ID.
//
// see https://stripe.com/docs/api#delete_customer
func (self *CustomerClient) Delete(id string) (*Customer, error) {
@@ -140,11 +109,15 @@ func (self *CustomerClient) Delete(id string) (*Customer, error) {
return &customer, err
}
+// Returns a list of your Customers.
+//
// see https://stripe.com/docs/api#list_customers
func (self *CustomerClient) List() ([]*Customer, error) {
return self.ListN(10, 0)
}
+// Returns a list of your Customers at the specified range.
+//
// see https://stripe.com/docs/api#list_customers
func (self *CustomerClient) ListN(count int, offset int) ([]*Customer, error) {
// define a wrapper function for the Customer List, so that we can
@@ -189,6 +162,8 @@ func appendCustomerParamsToValues(c *CustomerParams, values *url.Values) {
// add optional credit card details, if specified
if c.Card != nil {
appendCardParamsToValues(c.Card, values)
+ } else if len(c.Token) != 0 {
+ values.Add("card", c.Token)
}
}
View
46 customer_test.go
@@ -65,11 +65,39 @@ func TestCreateCustomer(t *testing.T) {
if err != nil {
t.Errorf("Expected Customer, got Error %s", err.Error())
}
- if cust.Email != cust1.Email {
- t.Errorf("Expected Customer Email %s, got %s", cust1.Email, cust.Email)
+ if string(cust.Email) != cust1.Email {
+ t.Errorf("Expected Customer Email %s, got %v", cust1.Email, cust.Email)
}
- if cust.Desc != cust1.Desc {
- t.Errorf("Expected Customer Desc %s, got %s", cust1.Desc, cust.Desc)
+ if string(cust.Desc) != cust1.Desc {
+ t.Errorf("Expected Customer Desc %s, got %v", cust1.Desc, cust.Desc)
+ }
+}
+
+// TestCreateCustomerToken will test that we can successfully Create a Customer
+// using a credit card Token.
+func TestCreateCustomerToken(t *testing.T) {
+
+ // Create a Token for the credit card
+ token, _ := Tokens.Create(&token1)
+
+ // Create a Charge that uses a Token
+ cust := CustomerParams{
+ Token: token.Id,
+ Desc: "Customer for site@stripe.com",
+ }
+
+ // Create the charge
+ resp, err := Customers.Create(&cust)
+ defer Customers.Delete(resp.Id)
+ if err != nil {
+ t.Errorf("Expected Create Customer, got Error %s", err.Error())
+ }
+ if resp.Card == nil {
+ t.Errorf("Expected Customer Card from Token, got nil")
+ }
+ // Sanity check to make sure card was attached to customer
+ if string(resp.Card.Name) != string(token.Card.Name) {
+ t.Errorf("Expected Card Name %s, got %v", token.Card.Name, resp.Card.Name)
}
}
@@ -96,11 +124,11 @@ func TestRetrieveCustomer(t *testing.T) {
if err != nil {
t.Errorf("Expected Customer, got Error %s", err.Error())
}
- if cust.Email != cust2.Email {
- t.Errorf("Expected Customer Email %s, got %s", cust2.Email, cust.Email)
+ if string(cust.Email) != cust2.Email {
+ t.Errorf("Expected Customer Email %s, got %v", cust2.Email, cust.Email)
}
- if cust.Desc != cust2.Desc {
- t.Errorf("Expected Customer Desc %s, got %s", cust2.Desc, cust.Desc)
+ if string(cust.Desc) != cust2.Desc {
+ t.Errorf("Expected Customer Desc %s, got %v", cust2.Desc, cust.Desc)
}
if cust.Card == nil {
t.Errorf("Expected Credit Card %s, got nil", cust2.Card.Number)
@@ -167,7 +195,7 @@ func TestListCustomers(t *testing.T) {
defer Customers.Delete(resp2.Id)
// get the list from Stripe
- customers, err := Customers.List()
+ customers, err := Customers.ListN(2, 0)
if err != nil {
t.Errorf("Expected Customer List, got Error %s", err.Error())
}

0 comments on commit 2121281

Please sign in to comment.
Something went wrong with that request. Please try again.