flamingo.me/flamingo-commerce/v3@v3.11.0/payment/interfaces/offlinePaymentGateway.go (about)

     1  package interfaces
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"net/url"
     8  
     9  	cartDomain "flamingo.me/flamingo-commerce/v3/cart/domain/cart"
    10  	"flamingo.me/flamingo-commerce/v3/cart/domain/placeorder"
    11  	"flamingo.me/flamingo-commerce/v3/payment/domain"
    12  	"flamingo.me/flamingo/v3/framework/web"
    13  )
    14  
    15  // OfflineWebCartPaymentGateway provides an offline payment integration
    16  type OfflineWebCartPaymentGateway struct {
    17  	enabled   bool
    18  	responder *web.Responder
    19  }
    20  
    21  const (
    22  	// OfflineWebCartPaymentGatewayCode - the gateway code
    23  	OfflineWebCartPaymentGatewayCode = "offline"
    24  )
    25  
    26  var _ WebCartPaymentGateway = (*OfflineWebCartPaymentGateway)(nil)
    27  
    28  // Inject for OfflineWebCartPaymentGateway
    29  func (o *OfflineWebCartPaymentGateway) Inject(responder *web.Responder, config *struct {
    30  	Enabled bool `inject:"config:checkout.enableOfflinePaymentProvider,optional"`
    31  }) {
    32  	o.responder = responder
    33  	if config != nil {
    34  		o.enabled = config.Enabled
    35  	}
    36  }
    37  
    38  // Methods returns the Payment Providers available Payment Methods
    39  func (o *OfflineWebCartPaymentGateway) Methods() []domain.Method {
    40  	return []domain.Method{
    41  		{
    42  			Title: "cash on delivery",
    43  			Code:  "offlinepayment_cashondelivery",
    44  		},
    45  		{
    46  			Title: "cash in advance",
    47  			Code:  "offlinepayment_cashinadvance",
    48  		},
    49  	}
    50  }
    51  
    52  func (o *OfflineWebCartPaymentGateway) isSupportedMethod(method string) bool {
    53  	for _, m := range o.Methods() {
    54  		if m.Code == method {
    55  			return true
    56  		}
    57  	}
    58  	return false
    59  }
    60  
    61  func (o *OfflineWebCartPaymentGateway) checkCart(currentCart *cartDomain.Cart) error {
    62  	// Read the infos in the cart and check precondition
    63  	if currentCart.PaymentSelection.Gateway() != OfflineWebCartPaymentGatewayCode {
    64  		return errors.New("cart is not supposed to be paid by this gateway")
    65  	}
    66  	for qualifier := range currentCart.PaymentSelection.CartSplit() {
    67  		if !o.isSupportedMethod(qualifier.Method) {
    68  			return errors.New("cart payment method not supported by gateway")
    69  		}
    70  	}
    71  	return nil
    72  }
    73  
    74  // StartFlow for offline payment and directly mark it as completed, since there is no online payment process
    75  func (o *OfflineWebCartPaymentGateway) StartFlow(ctx context.Context, currentCart *cartDomain.Cart, correlationID string, returnURL *url.URL) (*domain.FlowResult, error) {
    76  	err := o.checkCart(currentCart)
    77  	if err != nil {
    78  		return nil, err
    79  	}
    80  	return &domain.FlowResult{
    81  		Status: domain.FlowStatus{
    82  			Status: domain.PaymentFlowStatusCompleted,
    83  		},
    84  	}, nil
    85  }
    86  
    87  // FlowStatus for offline payment is always completed
    88  func (o *OfflineWebCartPaymentGateway) FlowStatus(ctx context.Context, cart *cartDomain.Cart, correlationID string) (*domain.FlowStatus, error) {
    89  	return &domain.FlowStatus{
    90  		Status: domain.PaymentFlowStatusCompleted,
    91  	}, nil
    92  }
    93  
    94  // ConfirmResult nothing to confirm  for offline payment
    95  func (o *OfflineWebCartPaymentGateway) ConfirmResult(ctx context.Context, cart *cartDomain.Cart, cartPayment *placeorder.Payment) error {
    96  	return nil
    97  }
    98  
    99  // OrderPaymentFromFlow create the order payment from the current cart/flow
   100  func (o *OfflineWebCartPaymentGateway) OrderPaymentFromFlow(ctx context.Context, currentCart *cartDomain.Cart, correlationID string) (*placeorder.Payment, error) {
   101  	err := o.checkCart(currentCart)
   102  	if err != nil {
   103  		return nil, err
   104  	}
   105  
   106  	cartPayment := placeorder.Payment{
   107  		Gateway: OfflineWebCartPaymentGatewayCode,
   108  	}
   109  
   110  	var i int
   111  	for qualifier, charge := range currentCart.PaymentSelection.CartSplit() {
   112  		cartPayment.Transactions = append(cartPayment.Transactions, placeorder.Transaction{
   113  			Method:            qualifier.Method,
   114  			Status:            placeorder.PaymentStatusOpen,
   115  			ValuedAmountPayed: charge.Value,
   116  			AmountPayed:       charge.Price,
   117  			TransactionID:     fmt.Sprintf("%v-%v", qualifier.Method, (i + 1)),
   118  		})
   119  	}
   120  
   121  	return &cartPayment, nil
   122  }
   123  
   124  // CancelOrderPayment nothing to cancel for offline payment
   125  func (o *OfflineWebCartPaymentGateway) CancelOrderPayment(ctx context.Context, cartPayment *placeorder.Payment) error {
   126  	return nil
   127  }