-
Notifications
You must be signed in to change notification settings - Fork 0
/
stripe.go
142 lines (116 loc) · 3.79 KB
/
stripe.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package main
import (
"fmt"
"github.com/stripe/stripe-go/v74"
"github.com/stripe/stripe-go/v74/paymentintent"
"github.com/stripe/stripe-go/v74/price"
"github.com/stripe/stripe-go/v74/product"
)
// ID of the product in a bundle discount
var HOODIE_IDS = [...]string{
"prod_O2mPalbP4HvHJc", // Hoodie - Cream
"prod_O2mMZ7N70DGrap", // Hoodie - Green
"prod_O2mMUWKTwsVC1U", // Hoodie - Black
"prod_O34lEdsgMSE8TY", // Hoodie Cream - Stealth
"prod_O34mEl0jE7T9UJ", // Hoodie Green - Stealth
"prod_O34lSQer1T3zUX", // Hoodie Black - Stealth
}
const HOODIE_AND_ONE_ITEM_DISCOUNT = 500
const HOODIE_AND_TWO_ITEMS_DISCOUNT = 1000
type item struct {
ID string `json:"id"`
NAME string `json:"name"`
PRICE int64 `json:"price"`
IMAGES []string `json:"images"`
DESCRIPTION string `json:"description"`
}
func stripeGetProducts() []item {
items := []item{}
params := &stripe.ProductListParams{}
params.Limit = stripe.Int64(100)
// Only return a single page of results. This is useful for testing.
params.Single = true
i := product.List(params)
for i.Next() {
p := i.Product()
// Trolled if no default price
value := int64(0)
if p.DefaultPrice != nil {
price, _ := price.Get(p.DefaultPrice.ID, nil)
value = price.UnitAmount
}
items = append(items, item{
ID: p.ID,
NAME: p.Name,
DESCRIPTION: p.Description,
IMAGES: p.Images,
PRICE: value,
})
}
return items
}
type intent struct {
CLIENT_SECRET string `json:"clientSecret"`
}
// Calculate the order total on the server to prevent
// people from directly manipulating the amount on the client
// ! Optional TODO - optimise by only requesting the ID's we actually need from Stripe.
func calculateOrderAmount(cart_items []cart_item) int64 {
all_items := stripeGetProducts()
var total_price int64 = 0
var total_items int = 0
var hoodie_in_cart bool = false
for _, cart_item := range cart_items {
hoodie_in_cart = hoodie_in_cart || itemIsHoodie(cart_item.ID)
total_price += findItemPrice(all_items, cart_item.ID)
total_items++
}
// Discount to apply (in cents)
var discount int64 = 0
if !hoodie_in_cart {
fmt.Print("\tNo hoodies in cart. Discount not applied.\n")
} else if total_items >= 3 {
fmt.Printf("\tHoodie and >= two other items in cart. %vc discount applied.\n", HOODIE_AND_TWO_ITEMS_DISCOUNT)
discount += HOODIE_AND_TWO_ITEMS_DISCOUNT
} else if total_items >= 2 {
fmt.Printf("\tHoodie and one other item in cart. %vc discount applied.\n", HOODIE_AND_ONE_ITEM_DISCOUNT)
discount += HOODIE_AND_ONE_ITEM_DISCOUNT
}
total_price = max(50, total_price-discount)
fmt.Printf("\tTotal number of items: %v\n", total_items)
fmt.Printf("\tDiscount applied: %vc\n", discount)
fmt.Printf("\tThe total price (after discount): %vc\n", total_price)
// Price must be at least $0.50 AUD, as per Stripe's minimum
return total_price
}
func findItemPrice(items []item, id string) int64 {
for i := 0; i < len(items); i++ {
if items[i].ID == id {
return items[i].PRICE
}
}
return 0
}
func itemIsHoodie(item_id string) bool {
for _, hoodie_id := range HOODIE_IDS {
fmt.Printf("\tThis hoodie ID was checked: %v\n", hoodie_id)
if item_id == hoodie_id {
fmt.Printf("\tThis hoodie ID was matched: %v\n", hoodie_id)
return true
}
}
fmt.Printf("\tThis item is not a hoodie: %v\n", item_id)
return false
}
func stripeCreatePaymentIntent(items []cart_item, email string) intent {
params := &stripe.PaymentIntentParams{
Amount: stripe.Int64(calculateOrderAmount(items)),
Currency: stripe.String(string(stripe.CurrencyAUD)),
AutomaticPaymentMethods: &stripe.PaymentIntentAutomaticPaymentMethodsParams{
Enabled: stripe.Bool(true),
},
ReceiptEmail: stripe.String(email),
}
pi, _ := paymentintent.New(params)
return intent{CLIENT_SECRET: pi.ClientSecret}
}