card

package
v5.2.0--beta+incompatible Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 20, 2018 License: MIT Imports: 26 Imported by: 4

Documentation

Overview

Package card implements functionality to add, remove, charge, and issue refunds for credit cards as well as view reports for lists of charges and refunds.

Charges are performed via Stripe. This package requires loading the Stripe private key for your Stripe account when the app starts. The private key should be in the app.yaml file as an environmental variable.

When a card is added to the app, very minimal (expiration and last 4) of the card's data is actually stored in App Engine. The card's information is sent to Stripe who then returns an id for this card. When a charge is processed, this id is sent to Stripe and Stripe looks up the card's information to charge it. The information stored in App Engine is safe, as in if someone were to get the data, it could not be used to process charges. No credit card number is stored. The data is just used to identify the card so users of the app know which card they are charging.

Datastore ID: the ID of the entity (think sql "row") in the App Engine Datastore. Customer ID: the ID that the user provides that links the card to a company. This is usually from a CRM software. Stripe ID: the ID stripe uses to process a charge. Also known as the stripe customer token. For each datastore ID, there should be one and only one customer ID and stripe ID. For each customer ID, there can be many datastore IDs and stripe IDs; one for each card added. For each stripe ID, there should be one and only one datastore ID and customer ID.

Index

Constants

This section is empty.

Variables

View Source
var Config = config{
	StripeSecretKey:      "",
	StripePublishableKey: "",
}

Config is a copy of the config struct with some defaults set

Functions

func Add

func Add(w http.ResponseWriter, r *http.Request)

Add saves a new card the the datastore This is done by validating the inputs, sending the card token to Stripe, and saving the customer ID from Stripe to the datastore (along with some other info). The card token was generated client side by stripe.js. Stripe.js takes the card number, expiration, and security code and sends it to Stripe. It returns a token for us to use. This makes it so we never "touch" or save the actually card information. The customer ID that we get back from Stripe is used to process charges in the future.

func AutoCharge

func AutoCharge(w http.ResponseWriter, r *http.Request)

AutoCharge processes a charge on a credit card automatically this is used to charge a card without using the gui

func Capture

func Capture(w http.ResponseWriter, r *http.Request)

Capture captures a previous authorized charge

func CreateStripeClient

func CreateStripeClient(c context.Context) *client.API

CreateStripeClient creates an httpclient on a per-request basis for use in making api calls to Stripe Stripe's API is accessed via http requests, need a way to make these requests. This func returns an httpclient on a per request basis (per http request made to this app).

func GetAll

func GetAll(w http.ResponseWriter, r *http.Request)

GetAll retrieves the list of all cards in the datastore This only gets the datastore id and customer name. This is used to build the datalist in the gui of customers who we can process a charge for.

func GetOne

func GetOne(w http.ResponseWriter, r *http.Request)

GetOne retrieves the full data for one card from the datastore This is used to fill in the "charge card" panel with identifying info on the card so the user can verify they are charging the correct card.

func ManualCharge

func ManualCharge(w http.ResponseWriter, r *http.Request)

ManualCharge processes a charge on a credit card this is used when a user clicks the charge button in the gui

func Refund

func Refund(w http.ResponseWriter, r *http.Request)

Refund handles refunding a charge on a card

func RemoveAPI

func RemoveAPI(w http.ResponseWriter, r *http.Request)

RemoveAPI removes a card from the datastore and stripe This removes a card based upon the datastore ID. This ID is tied into one Stripe customer and one card.

func RemoveExpiredCards

func RemoveExpiredCards(w http.ResponseWriter, r *http.Request)

RemoveExpiredCards removes old cards This works by looking up cards whose expiration is a given month/year string. Unfortunately this means that if this func doesn't run or encounters an error, cards older than the month/year will not be removed. However, they will eventually get taken care of by RemoveUnusedCards. We do a "select" then a "delete" because we need the Stripe information to remove the card from Stripe. This is designed to be run monthly as a cron task.

func RemoveUnusedCards

func RemoveUnusedCards(w http.ResponseWriter, r *http.Request)

RemoveUnusedCards removes card that we haven't charged in over 1 year We remove old cards to keep the db, Stripe, and the GUI dropdown menu of available cards cleaner. This works by looking up cards whose LastUsedTimestamp is greater than 1 year ago. We do a "select" then a "delete" because we need the Stripe information to remove the card from Stripe. This is designed to be run monthly as a cron task.

func Report

func Report(w http.ResponseWriter, r *http.Request)

Report gets the data for charges and refunds by the defined filters (date range and customer) and builds the reports page The reports show up in a different page so they are easily printable and more easily inspected. Date range is inclusive of start and end day.

func SetConfig

func SetConfig(c config) error

SetConfig saves the configuration options for charging cards these config options are references in other code directly from the variable Config

Types

type ChargeData

type ChargeData struct {
	ID            string `json:"charge_id,omitempty"`          //the stripe charge id
	AmountCents   int64  `json:"amount_cents,omitempty"`       //the amount of the charge in cents
	AmountDollars string `json:"amount_dollars,omitempty"`     //amount of the charge in dollars (without $ symbol)
	Captured      bool   `json:"captured,omitempty"`           //determines if the charge was successfully placed on a real credit card
	CapturedStr   string `json:"captured_string,omitempty"`    //see above
	Timestamp     string `json:"timestamp,omitempty"`          //unix timestamp of the time that stripe charged the card
	Invoice       string `json:"invoice_num,omitempty"`        //some extra info that was provided when the user processed the charge
	Po            string `json:"po_num,omitempty"`             // " " " "
	StripeCustID  string `json:"stripe_customer_id,omitempty"` //this is the id given to the customer by stripe and is used to charge the card
	Customer      string `json:"customer_name,omitempty"`      //name of the customer from the app engine datastore, the name of the company a card belongs to
	CustomerID    string `json:"customer_id,omitempty"`        //the unique id you gave the customer when you saved the card, from a CRM
	User          string `json:"username,omitempty"`           //username of the user who charged the card
	Cardholder    string `json:"cardholder,omitempty"`         //name on the card
	LastFour      string `json:"last4,omitempty"`              //used to identify the card when looking at the receipt or in a report
	Expiration    string `json:"expiration,omitempty"`         // " " " "
	CardBrand     string `json:"card_brand,omitempty"`         // " " " "

	//data for automatically completed charges (api request charges)
	AutoCharge         bool   `json:"auto_charge,omitempty"`          //true if we made this charge automatically through api request
	AutoChargeReferrer string `json:"auto_charge_referrer,omitempty"` //the name of the app that requested the charge
	AutoChargeReason   string `json:"auto_charge_reason,omitempty"`   //if one app/referrer will place charges for many reasons, detail that reason here; so we know what process/func caused the charge

	//data about an authed & captured charge
	AuthorizedByUser   string `json:"authorized_by_user"`
	AuthorizedDatetime string `json:"authorized_datetime"`
	ProcessedDatetime  string `json:"processed_datetime"`

	//data used to differentiate between a not captured and failed charge and a non captured but authorized charge
	//null if charge is successful or charge was authorized, if charged failed there will be some info
	FailureCode    string
	FailureMessage string
}

ChargeData is the data from a charge that we use to build the gui Stripe's charge struct (stripe.Charge) returns a lot more info than we need so we don't use it.

func ExtractDataFromCharge

func ExtractDataFromCharge(chg *stripe.Charge) (data ChargeData)

ExtractDataFromCharge pulls out the fields of data we want from a stripe charge object we only need certain info from the stripe charge object, this pulls the needed fields out also does some formating for using the data in the gui

type CustomerDatastore

type CustomerDatastore struct {
	CustomerID          string `datastore:"CustomerId" json:"customer_id"` //the CRM ID of the customer.
	CustomerName        string `json:"customer_name"`                      //the name of the customer, usually this is the company an individual card holder works for
	Cardholder          string `json:"cardholder_name"`                    //the name on the card
	CardExpiration      string `json:"card_expiration"`                    //used to just show in the gui which card is on file, MM/YYYY
	CardLast4           string `json:"card_last4"`                         //used to just show in the gui which card is on file
	StripeCustomerToken string `json:"-"`                                  //the id returned when a card is saved via Stripe, this id uniquely identifies this card for this customer
	DatetimeCreated     string `json:"-"`                                  //when was this card added to the app
	AddedByUser         string `json:"added_by"`                           //which user of the app saved the card
	LastUsedTimestamp   int64  `json:"-"`                                  //the unix timestamp of the time the card was last charged, used to remove cards we don't use anymore (lost customer)

	//fields not used in cloud datastore
	ID int64 `json:"sqlite_user_id"`
}

CustomerDatastore is the data stored in the db (Google Cloud Datatore) about a customer. This information is added when a new customer/card is added. We use this data to process charges for a customer by linking our CRM id or customer name to Stripe's id for the card. In the Google Cloud Datastore each customer is saved as an entity (think sql row). Each entity has a key that is used to look it up. This key is not included in the entity unlike an ID column in a sql row. This key has a subcomponent called anID. This is referred to as the "datastore ID".

func FindByCustomerID

func FindByCustomerID(c context.Context, customerID string) (CustomerDatastore, error)

FindByCustomerID retrieves a card's information by the unique id from a CRM system This id was provided when a card was added to this app. This func is used when making api style request to semi-automate the charging of a card. only getting the fields we need to show data in the charge card panel

type List

type List struct {
	CustomerName string `json:"customer_name"` //company name for the card
	ID           int64  `json:"id"`            //the datastore id of the card, this is what uniquely identifies the card in the datatore so we can look data.
}

List is used to return the list of cards available to be charged to build the gui The list is used to build the autocomplete datalist in the UI.

type RefundData

type RefundData struct {
	Refunded      bool   //was this a refund, should always be true
	AmountCents   int64  //the amount of the refund in cents, this amount can be less than or equal to the corresponding charge
	AmountDollars string //amount of the refund in dollars (without $ symbol)
	Timestamp     string //unix timestamp of the time that stripe refunded the card
	Invoice       string //metadata field with extra info on the charge
	LastFour      string //used to identify the card when looking at a report
	Expiration    string //" " " "
	Customer      string //name of the customer from the app engine datastore, name of the customer we charged
	User          string //username of the user who refunded the card
	Reason        string //why was the card refunded, this is a special value dictated by stripe
}

RefundData is the data from a refund that we use the build the gui Stripe returns more info thatn we need so we use our own struct to organize the data better

func ExtractRefundsFromEvents

func ExtractRefundsFromEvents(eventList *event.Iter) (r []RefundData)

ExtractRefundsFromEvents pulls out the data for each refund from the list of events and formats the data as needed stripe does not allow easy retrieving of refund data like charge data have to search in the "history" aka event log for refunds then have to parse the data since the data is in json format and there is no easy way to convert the data to a struct note: there can be many refunds for a single charge (that total less than or equal to the total amount charged)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL