Documentation
¶
Overview ¶
Package webhook provides services for polling for refund pending loans.
Package webhook provides services for processing payment provider webhook events.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AlertService ¶
type AlertService interface {
// AlertOps sends an alert to the operations team.
AlertOps(subject string, message string) error
}
AlertService is the interface for sending operational alerts.
type DisbursementUpdater ¶
type DisbursementUpdater interface {
// UpdateDisbursementStatus updates the disbursement status for a loan identified by sequenceID.
UpdateDisbursementStatus(sequenceID string, status string) error
// NotifyDisbursementComplete sends a notification (SMS) to the user that their disbursement completed.
NotifyDisbursementComplete(sequenceID string) error
// NotifyDisbursementFailed sends a notification (SMS) to the user that their disbursement failed.
NotifyDisbursementFailed(sequenceID string) error
// RepayVault returns borrowed USDC from treasury to the vault pool for the
// loan identified by sequenceID. No-op if already repaid.
RepayVault(sequenceID string) error
}
DisbursementUpdater is the interface for updating loan disbursement status. Implemented by the loan/disbursement service.
type RefundPendingFetcher ¶
type RefundPendingFetcher interface {
// GetRefundPendingDisbursements returns (sequenceID, paymentID) pairs for all
// disbursements in DisbursementRefundPending status.
GetRefundPendingDisbursements() ([]RefundPendingRecord, error)
}
RefundPendingFetcher retrieves loans that are awaiting crypto refund from YellowCard.
type RefundPendingRecord ¶
type RefundPendingRecord struct {
SequenceID string // YC sequenceId / idempotency key
PaymentID string // YC payment ID
LoanID string // Loan ID for tracking
UserID string // User ID for tracking
RecipientName string // Recipient name for fiat disbursement
AmountUSD float64 // Amount in USD
AmountStroops int64 // Amount in stroops (USDC * 10^7)
RampFiatAmount int64 // Original off-ramp fiat amount in cents (local currency)
RampFiatCurrency string // Original off-ramp fiat currency (e.g. "KES")
DestinationPhone string // Recipient phone number
CountryCode string // ISO country code
NetworkCode string // MoMo network code
NetworkName string // MoMo network name
}
RefundPendingRecord identifies a disbursement awaiting refund, including the data needed to attempt a fiat failover.
type RefundPoller ¶
type RefundPoller struct {
// contains filtered or unexported fields
}
RefundPoller periodically checks YellowCard for refund status on disbursements that failed after USDC was sent (direct settlement F3 failover).
Flow:
- Fetch loans in DisbursementRefundPending status from local DB
- For each, call YC API to check current status
- On "refunded" → update to DisbursementRefundReceived, attempt fiat failover
- On "refund_failed" → update to DisbursementFailed, alert ops
- On "pending_refund" / "refund_processing" → skip, poll again next cycle
func NewRefundPoller ¶
func NewRefundPoller( ycAdapter *yellowcard.YellowcardAdapter, offRamp adapters.OffRampService, fetcher RefundPendingFetcher, disbursement DisbursementUpdater, alerts AlertService, transactions TransactionRecorder, config RefundPollerConfig, ) *RefundPoller
NewRefundPoller creates a new RefundPoller.
func (*RefundPoller) Start ¶
func (p *RefundPoller) Start(ctx context.Context)
Start runs the RefundPoller in a background goroutine. It polls until the context is cancelled (graceful shutdown).
type RefundPollerConfig ¶
RefundPollerConfig configures the refund polling behavior.
func DefaultRefundPollerConfig ¶
func DefaultRefundPollerConfig() RefundPollerConfig
DefaultRefundPollerConfig returns sensible defaults.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service processes incoming payment provider webhook events.
func NewService ¶
func NewService(disbursements DisbursementUpdater, alerts AlertService, transactions TransactionRecorder) *Service
NewService creates a new webhook processing service.
func (*Service) ProcessYellowCardEvent ¶
func (s *Service) ProcessYellowCardEvent(event yellowcard.WebhookEvent) error
ProcessYellowCardEvent handles a single YellowCard webhook event by mapping it to the appropriate disbursement status update and side effects.
Event → Action mapping:
DISBURSEMENT.COMPLETE / PAYMENT.COMPLETE → DisbursementComplete + notify user DISBURSEMENT.FAILED / PAYMENT.FAILED → if direct: DisbursementRefundPending; if fiat: DisbursementFailed + alert ops PENDING_LIQUIDITY → alert ops (YC balance low, auto-retries for 2hrs) REFUNDED → DisbursementRefundReceived (RefundPoller handles fiat failover) REFUND_FAILED → DisbursementFailed + alert ops EXPIRED / CANCELLED → treat as FAILED PROCESSING / PENDING / PROCESS → DisbursementProcessing
type TransactionRecorder ¶
type TransactionRecorder interface {
// UpdateTransactionByExternalID updates an existing transaction found by its external ID.
UpdateTransactionByExternalID(ctx context.Context, externalID string, status string, externalStatus string) error
// RecordFiatFailover records a fiat failover transaction after a direct settlement refund.
RecordFiatFailover(ctx context.Context, rec RefundPendingRecord, newRequestID string) error
}
TransactionRecorder records and updates transaction records for disbursement events.
type WebhookEventHandler ¶
type WebhookEventHandler interface {
// ProcessYellowCardEvent handles a single webhook event, mapping it to the
// appropriate disbursement status update and triggering any side effects.
ProcessYellowCardEvent(event yellowcard.WebhookEvent) error
}
WebhookEventHandler processes incoming YellowCard webhook events.