Example #1
0
func createSubItem(t *testing.T) (*stripe.Sub, *stripe.SubItem, func()) {
	customerParams := &stripe.CustomerParams{
		Source: &stripe.SourceParams{
			Card: &stripe.CardParams{
				Number: "378282246310005",
				Month:  "06",
				Year:   "20",
			},
		},
	}

	cust, err := customer.New(customerParams)
	if err != nil {
		t.Fatalf("customer creation: %s", err)
	}

	planID := fmt.Sprintf("test-%d", rand.Int63())
	planParams := &stripe.PlanParams{
		ID:       planID,
		Name:     "Test Plan",
		Amount:   99,
		Currency: currency.USD,
		Interval: plan.Month,
	}

	p, err := plan.New(planParams)
	if err != nil {
		t.Fatalf("plan creation: %s", err)
	}

	subParams := &stripe.SubParams{
		Customer: cust.ID,
		Items: []*stripe.SubItemsParams{
			{
				Plan:     p.ID,
				Quantity: 1,
			},
		},
	}

	target, err := sub.New(subParams)
	if err != nil {
		t.Fatalf("subscription creation: %s", err)
	}
	if target.Items == nil {
		t.Fatalf("no items for sub %s", target.ID)
	}
	if len(target.Items.Values) != 1 {
		t.Fatalf("missing items: %#v", target)
	}
	return target, target.Items.Values[0], func() {
		sub.Cancel(target.ID, nil)
		plan.Del(p.ID)
		customer.Del(cust.ID)
	}
}
Example #2
0
// Invoices are somewhat painful to test since you need
// to first have some items, so test everything together to
// avoid unnecessary duplication
func TestAllInvoicesScenarios(t *testing.T) {
	customerParams := &stripe.CustomerParams{
		Source: &stripe.SourceParams{
			Card: &stripe.CardParams{
				Number: "378282246310005",
				Month:  "06",
				Year:   "20",
			},
		},
	}

	cust, _ := customer.New(customerParams)

	item := &stripe.InvoiceItemParams{
		Customer: cust.ID,
		Amount:   100,
		Currency: currency.USD,
		Desc:     "Test Item",
	}

	targetItem, err := invoiceitem.New(item)

	if err != nil {
		t.Error(err)
	}

	if targetItem.Customer.ID != item.Customer {
		t.Errorf("Item customer %q does not match expected customer %q\n", targetItem.Customer.ID, item.Customer)
	}

	if targetItem.Desc != item.Desc {
		t.Errorf("Item description %q does not match expected description %q\n", targetItem.Desc, item.Desc)
	}

	if targetItem.Amount != item.Amount {
		t.Errorf("Item amount %v does not match expected amount %v\n", targetItem.Amount, item.Amount)
	}

	if targetItem.Currency != item.Currency {
		t.Errorf("Item currency %q does not match expected currency %q\n", targetItem.Currency, item.Currency)
	}

	if targetItem.Date == 0 {
		t.Errorf("Item date is not set\n")
	}

	invoiceParams := &stripe.InvoiceParams{
		Customer:   cust.ID,
		Desc:       "Desc",
		Statement:  "Statement",
		TaxPercent: 20.0,
	}

	targetInvoice, err := New(invoiceParams)

	if err != nil {
		t.Error(err)
	}

	if targetInvoice.Customer.ID != invoiceParams.Customer {
		t.Errorf("Invoice customer %q does not match expected customer %q\n", targetInvoice.Customer.ID, invoiceParams.Customer)
	}

	if targetInvoice.TaxPercent != invoiceParams.TaxPercent {
		t.Errorf("Invoice tax percent %f does not match expected tax percent %f\n", targetInvoice.TaxPercent, invoiceParams.TaxPercent)
	}

	if targetInvoice.Tax != 20 {
		t.Errorf("Invoice tax  %v does not match expected tax 20\n", targetInvoice.Tax)
	}

	if targetInvoice.Amount != targetItem.Amount+targetInvoice.Tax {
		t.Errorf("Invoice amount %v does not match expected amount %v + tax %v\n", targetInvoice.Amount, targetItem.Amount, targetInvoice.Tax)
	}

	if targetInvoice.Currency != targetItem.Currency {
		t.Errorf("Invoice currency %q does not match expected currency %q\n", targetInvoice.Currency, targetItem.Currency)
	}

	if targetInvoice.Date == 0 {
		t.Errorf("Invoice date is not set\n")
	}

	if targetInvoice.Start == 0 {
		t.Errorf("Invoice start is not set\n")
	}

	if targetInvoice.End == 0 {
		t.Errorf("Invoice end is not set\n")
	}

	if targetInvoice.Total != targetInvoice.Amount || targetInvoice.Subtotal != targetInvoice.Amount-targetInvoice.Tax {
		t.Errorf("Invoice total %v and subtotal %v do not match expected amount %v\n", targetInvoice.Total, targetInvoice.Subtotal, targetInvoice.Amount)
	}

	if targetInvoice.Desc != invoiceParams.Desc {
		t.Errorf("Invoice description %q does not match expected description %q\n", targetInvoice.Desc, invoiceParams.Desc)
	}

	if targetInvoice.Statement != invoiceParams.Statement {
		t.Errorf("Invoice statement %q does not match expected statement %q\n", targetInvoice.Statement, invoiceParams.Statement)
	}

	if targetInvoice.Lines == nil {
		t.Errorf("Invoice lines not found\n")
	}

	if targetInvoice.Lines.Count != 1 {
		t.Errorf("Invoice lines count %v does not match expected value\n", targetInvoice.Lines.Count)
	}

	if targetInvoice.Lines.Values == nil {
		t.Errorf("Invoice lines values not found\n")
	}

	if targetInvoice.Lines.Values[0].Amount != targetItem.Amount {
		t.Errorf("Invoice line amount %v does not match expected amount %v\n", targetInvoice.Lines.Values[0].Amount, targetItem.Amount)
	}

	if targetInvoice.Lines.Values[0].Currency != targetItem.Currency {
		t.Errorf("Invoice line currency %q does not match expected currency %q\n", targetInvoice.Lines.Values[0].Currency, targetItem.Currency)
	}

	if targetInvoice.Lines.Values[0].Desc != targetItem.Desc {
		t.Errorf("Invoice line description %q does not match expected description %q\n", targetInvoice.Lines.Values[0].Desc, targetItem.Desc)
	}

	if targetInvoice.Lines.Values[0].Type != TypeInvoiceItem {
		t.Errorf("Invoice line type %q does not match expected type\n", targetInvoice.Lines.Values[0].Type)
	}

	if targetInvoice.Lines.Values[0].Period == nil {
		t.Errorf("Invoice line period not found\n")
	}

	if targetInvoice.Lines.Values[0].Period.Start == 0 {
		t.Errorf("Invoice line period start is not set\n")
	}

	if targetInvoice.Lines.Values[0].Period.End == 0 {
		t.Errorf("Invoice line period end is not set\n")
	}

	updatedItem := &stripe.InvoiceItemParams{
		Amount:       99,
		Desc:         "Updated Desc",
		Discountable: true,
	}

	targetItemUpdated, err := invoiceitem.Update(targetItem.ID, updatedItem)

	if err != nil {
		t.Error(err)
	}

	if targetItemUpdated.Desc != updatedItem.Desc {
		t.Errorf("Updated item description %q does not match expected description %q\n", targetItemUpdated.Desc, updatedItem.Desc)
	}

	if targetItemUpdated.Amount != updatedItem.Amount {
		t.Errorf("Updated item amount %v does not match expected amount %v\n", targetItemUpdated.Amount, updatedItem.Amount)
	}

	if !targetItemUpdated.Discountable {
		t.Errorf("Updated item is not discountable")
	}

	updatedInvoice := &stripe.InvoiceParams{
		Desc:      "Updated Desc",
		Statement: "Updated",
	}

	targetInvoiceUpdated, err := Update(targetInvoice.ID, updatedInvoice)

	if err != nil {
		t.Error(err)
	}

	if targetInvoiceUpdated.Desc != updatedInvoice.Desc {
		t.Errorf("Updated invoice description %q does not match expected description %q\n", targetInvoiceUpdated.Desc, updatedInvoice.Desc)
	}

	if targetInvoiceUpdated.Statement != updatedInvoice.Statement {
		t.Errorf("Updated invoice statement %q does not match expected statement %q\n", targetInvoiceUpdated.Statement, updatedInvoice.Statement)
	}

	_, err = invoiceitem.Get(targetItem.ID, nil)
	if err != nil {
		t.Error(err)
	}

	ii := invoiceitem.List(&stripe.InvoiceItemListParams{Customer: cust.ID})
	for ii.Next() {
		if ii.InvoiceItem() == nil {
			t.Error("No nil values expected")
		}

		if ii.Meta() == nil {
			t.Error("No metadata returned")
		}
	}
	if err := ii.Err(); err != nil {
		t.Error(err)
	}

	i := List(&stripe.InvoiceListParams{Customer: cust.ID})
	for i.Next() {
		if i.Invoice() == nil {
			t.Error("No nil values expected")
		}

		if i.Meta() == nil {
			t.Error("No metadata returned")
		}
	}
	if err := i.Err(); err != nil {
		t.Error(err)
	}

	il := ListLines(&stripe.InvoiceLineListParams{ID: targetInvoice.ID, Customer: cust.ID})
	for il.Next() {
		if il.InvoiceLine() == nil {
			t.Error("No nil values expected")
		}

		if il.Meta() == nil {
			t.Error("No metadata returned")
		}
	}
	if err := il.Err(); err != nil {
		t.Error(err)
	}

	iiDel, err := invoiceitem.Del(targetItem.ID)

	if err != nil {
		t.Error(err)
	}

	if !iiDel.Deleted {
		t.Errorf("Invoice Item id %q expected to be marked as deleted on the returned resource\n", iiDel.ID)
	}

	_, err = Get(targetInvoice.ID, nil)

	if err != nil {
		t.Error(err)
	}

	planParams := &stripe.PlanParams{
		ID:       "test",
		Name:     "Test Plan",
		Amount:   99,
		Currency: currency.USD,
		Interval: plan.Month,
	}

	_, err = plan.New(planParams)
	if err != nil {
		t.Error(err)
	}

	subParams := &stripe.SubParams{
		Customer:    cust.ID,
		Plan:        planParams.ID,
		Quantity:    10,
		TrialEndNow: true,
	}

	subscription, err := sub.New(subParams)
	if err != nil {
		t.Error(err)
	}

	nextParams := &stripe.InvoiceParams{
		Customer:         cust.ID,
		Sub:              subscription.ID,
		SubPlan:          planParams.ID,
		SubNoProrate:     false,
		SubProrationDate: time.Now().AddDate(0, 0, 12).Unix(),
		SubQuantity:      1,
		SubTrialEnd:      time.Now().AddDate(0, 0, 12).Unix(),
	}

	nextInvoice, err := GetNext(nextParams)
	if err != nil {
		t.Error(err)
	}

	if nextInvoice.Customer.ID != cust.ID {
		t.Errorf("Invoice customer %v does not match expected customer%v\n", nextInvoice.Customer.ID, cust.ID)
	}

	if nextInvoice.Sub != subscription.ID {
		t.Errorf("Invoice subscription %v does not match expected subscription%v\n", nextInvoice.Sub, subscription.ID)
	}

	closeInvoice := &stripe.InvoiceParams{
		Closed: true,
	}

	targetInvoiceClosed, err := Update(targetInvoice.ID, closeInvoice)

	if err != nil {
		t.Error(err)
	}

	if targetInvoiceClosed.Closed != closeInvoice.Closed {
		t.Errorf("Invoice was not closed as expected and its value is %v", targetInvoiceClosed.Closed)
	}

	openInvoice := &stripe.InvoiceParams{
		NoClosed: true,
	}

	targetInvoiceOpened, err := Update(targetInvoice.ID, openInvoice)

	if err != nil {
		t.Error(err)
	}

	if targetInvoiceOpened.Closed != false {
		t.Errorf("Invoice was not reponed as expected and its value is %v", targetInvoiceOpened.Closed)
	}

	_, err = plan.Del(planParams.ID)
	if err != nil {
		t.Error(err)
	}

	customer.Del(cust.ID)
}
Example #3
0
// EnsureSubscriptionForGroup ensures subscription for a group
func EnsureSubscriptionForGroup(groupName string, params *stripe.SubParams) (*stripe.Sub, error) {
	if params == nil {
		params = &stripe.SubParams{
			Plan: Plans[UpTo10Users].ID,
		}
	}

	group, err := modelhelper.GetGroup(groupName)
	if err != nil {
		return nil, err
	}

	if group.Payment.Subscription.ID != "" {
		return sub.Get(group.Payment.Subscription.ID, nil)
	}

	if group.Payment.Customer.ID == "" {
		return nil, ErrCustomerNotExists
	}

	if err := CheckCustomerHasSource(group.Payment.Customer.ID); err != nil {
		return nil, err
	}

	now := time.Now().UTC()
	thirtyDaysLater := now.Add(30 * 24 * time.Hour).Unix()
	sevenDaysLater := now.Add(7 * 24 * time.Hour).Unix()

	if params.TrialEnd != 0 {
		// we only allow 0, 7 and 30 day trials
		if params.TrialEnd < sevenDaysLater {
			params.TrialEnd = sevenDaysLater
		}

		if params.TrialEnd > sevenDaysLater {
			params.TrialEnd = thirtyDaysLater
		}
	}

	// override quantity and plan in case we did not charge the user previously
	// due to failed payment and the subscription is deleted by stripe, create
	// new subscription
	quantity := uint64(1)
	activeCount, _ := (&socialapimodels.PresenceDaily{}).CountDistinctByGroupName(groupName)
	if activeCount != 0 {
		quantity = uint64(activeCount)
		params.Plan = GetPlanID(activeCount)
		params.TrialEnd = 0
	}

	// only send our whitelisted params
	req := &stripe.SubParams{
		Customer: group.Payment.Customer.ID,
		Quantity: quantity,
		Plan:     params.Plan,
		Coupon:   params.Coupon,
		Token:    params.Token,
		TrialEnd: params.TrialEnd,
		Card:     params.Card,
	}

	sub, err := sub.New(req)
	if err != nil {
		return nil, err
	}

	if err := syncGroupWithCustomerID(group.Payment.Customer.ID); err != nil {
		return nil, err
	}

	return sub, nil
}