Skip to content

Instantly share code, notes, and snippets.

@spencer-kormos-gbf
Last active May 19, 2023 12:21
Show Gist options
  • Select an option

  • Save spencer-kormos-gbf/1f5da65755637c615c5f2971797668b7 to your computer and use it in GitHub Desktop.

Select an option

Save spencer-kormos-gbf/1f5da65755637c615c5f2971797668b7 to your computer and use it in GitHub Desktop.
Proposed Scheduled Payments API
package payments
import (
"time"
"github.com/google/uuid"
)
type ScheduledTransactionStatus string
const (
Cancelled ScheduledTransactionStatus = "Cancelled"
RefundFull ScheduledTransactionStatus = "FullyRefunded"
RefundPartial ScheduledTransactionStatus = "PartiallyRefunded"
Rescheduled ScheduledTransactionStatus = "Rescheduled"
Scheduled ScheduledTransactionStatus = "Scheduled"
Settled ScheduledTransactionStatus = "Settled"
)
type scheduler struct{}
// ListForParent returns a list of scheduled payments related to a parent transaction id and with specific statuses
// txID is the parent transaction id
// statuses is the list of statuses to include. Not including any statuses will return all transactions.
// Returns a list of Payment objects matching the request
func (s *scheduler) ListByParent(txID uuid.UUID, statuses ...ScheduledTransactionStatus) ([]*uuid.UUID, error) { //FIXME create a ScheduledPayment struct
return nil, nil
}
func (s *scheduler) List(paymentIDs []*uuid.UUID) ([]*uuid.UUID, error) { //FIXME create a ScheduledPayment struct to return
return nil, nil
}
// Multiple creates scheduled payments of the same amount, across a specified interval
// txID is the identifier of the parent checkout transaction
// numPayments is how many additional payments to spread out after the initial transaction is settled
// period is how far apart the payments should be spread apart
// amount is the amount to collect for each payment in millicents
// Returns a list of ids representing the ScheduledPayments that were created
func (s *scheduler) CreateMultiple(txId *uuid.UUID, numPayments int, period time.Duration, amountInMillis int64) (*uuid.UUID, error) {
return nil, nil
}
// Single creates a scheduled payment for the specific amount on the specific date
// txID is the identifier of the parent checkout transaction
// paymentDate is when to schedule the payment for. Only the date is honored, any time information is ignored
// Returns the ID of the scheduled payment that was created
func (s *scheduler) CreateSingle(txID *uuid.UUID, paymentDate time.Time, amountInMillis int64) (*uuid.UUID, error) {
return nil, nil
}
// Reschedule creates a new scheduled payment based off an existing scheduled payment that has occurred in the past
// paymentID is the identifier of the attempted scheduled payment
// period is the time from the originally scheduled payment for which to schedule the new payment. This must occur in the future.
// Returns the id of the new scheduled payment
func (s *scheduler) Reschedule(paymentID *uuid.UUID, interval time.Duration) (*uuid.UUID, error) {
return nil, nil
}
// Cancel sets all outstanding scheduled payments to cancelled, based off the parent checkout transaction
// Returns the ids of the scheduled payments that were Cancelled
func (s *scheduler) Cancel(txID *uuid.UUID) ([]*uuid.UUID, error) {
return nil, nil
}
// Refund applies a refund across the scheduled transactions associated with the parent transaction.
// Depending on the amount of the refund, and the remaining amount to be paid, this could succeed or return with different errors.
// Returns the all the updated scheduled payments (both those marked as refunded, and the newly scheduled payments with the new amounts)
func (s *scheduler) Refund(txID *uuid.UUID, amountInMillis int64) ([]*uuid.UUID, error) { // FIXME create a scheduled payment struct
return nil, nil
}
@arashbina
Copy link

overall I think it looks good. Couple of things:

  • There is a bit of inconsistency between APIs. For example Refund is supposed to know the logic of how to refund but other APIs are just doers and the logic is done outside of the scheduler. It's hard to judge the API without having the logic part (i.e. how the API is used). Peronally I think maybe scheduler can just purely schedule without knowing why and the caller is what holds the logic
  • I am sending context as the first parameter so that it can propagate tracing/logging. we should do the same here

@spencer-kormos-gbf
Copy link
Author

Yep, I forgot about the context, but will add.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment