flamingo.me/flamingo-commerce/v3@v3.11.0/test/integrationtest/projecttest/modules/payment/fake_gateway.go (about) 1 package payment 2 3 import ( 4 "context" 5 "errors" 6 "net/url" 7 8 "flamingo.me/flamingo-commerce/v3/cart/domain/cart" 9 "flamingo.me/flamingo-commerce/v3/cart/domain/placeorder" 10 "flamingo.me/flamingo-commerce/v3/payment/domain" 11 "flamingo.me/flamingo-commerce/v3/payment/interfaces" 12 ) 13 14 const ( 15 // FakePaymentGateway gateway code 16 FakePaymentGateway = "fake_payment_gateway" 17 ) 18 19 type ( 20 // FakeGateway used for testing all payment states 21 FakeGateway struct { 22 CartIsCompleted map[string]bool 23 } 24 25 // Method ... 26 Method struct { 27 Title string 28 Status *domain.FlowStatus 29 } 30 ) 31 32 var ( 33 _ interfaces.WebCartPaymentGateway = &FakeGateway{} 34 methods = map[string]Method{ 35 domain.PaymentFlowStatusCompleted: { 36 Title: "Payment completed", 37 Status: &domain.FlowStatus{ 38 Status: domain.PaymentFlowStatusCompleted, 39 }, 40 }, 41 domain.PaymentFlowStatusFailed: { 42 Title: "Payment failed", 43 Status: &domain.FlowStatus{ 44 Status: domain.PaymentFlowStatusFailed, 45 }, 46 }, 47 domain.PaymentErrorAbortedByCustomer: { 48 Title: "Payment aborted by customer", 49 Status: &domain.FlowStatus{ 50 Status: domain.PaymentErrorAbortedByCustomer, 51 }, 52 }, 53 domain.PaymentFlowStatusAborted: { 54 Title: "Payment aborted", 55 Status: &domain.FlowStatus{ 56 Status: domain.PaymentFlowStatusAborted, 57 }, 58 }, 59 domain.PaymentFlowStatusCancelled: { 60 Title: "Payment canceled", 61 Status: &domain.FlowStatus{ 62 Status: domain.PaymentFlowStatusCancelled, 63 }, 64 }, 65 domain.PaymentFlowStatusApproved: { 66 Title: "Payment approved", 67 Status: &domain.FlowStatus{ 68 Status: domain.PaymentFlowStatusApproved, 69 }, 70 }, 71 domain.PaymentFlowWaitingForCustomer: { 72 Title: "Payment waiting for customer", 73 Status: &domain.FlowStatus{ 74 Status: domain.PaymentFlowWaitingForCustomer, 75 }, 76 }, 77 domain.PaymentFlowActionShowIframe: { 78 Title: "Payment unapproved, iframe", 79 Status: &domain.FlowStatus{ 80 Status: domain.PaymentFlowStatusUnapproved, 81 Action: domain.PaymentFlowActionShowIframe, 82 ActionData: domain.FlowActionData{ 83 URL: &url.URL{Scheme: "https", Host: "url.com"}, 84 }, 85 }, 86 }, 87 domain.PaymentFlowActionRedirect: { 88 Title: "Payment unapproved, redirect", 89 Status: &domain.FlowStatus{ 90 Status: domain.PaymentFlowStatusUnapproved, 91 Action: domain.PaymentFlowActionRedirect, 92 ActionData: domain.FlowActionData{ 93 URL: &url.URL{Scheme: "https", Host: "url.com"}, 94 }, 95 }, 96 }, 97 domain.PaymentFlowActionPostRedirect: { 98 Title: "Payment unapproved, post-redirect", 99 Status: &domain.FlowStatus{ 100 Status: domain.PaymentFlowStatusUnapproved, 101 Action: domain.PaymentFlowActionPostRedirect, 102 ActionData: domain.FlowActionData{ 103 URL: &url.URL{Scheme: "https", Host: "url.com"}, 104 }, 105 }, 106 }, 107 domain.PaymentFlowActionShowHTML: { 108 Title: "Payment unapproved, html", 109 Status: &domain.FlowStatus{ 110 Status: domain.PaymentFlowStatusUnapproved, 111 Action: domain.PaymentFlowActionShowHTML, 112 ActionData: domain.FlowActionData{ 113 DisplayData: "<h2>test</h2>", 114 }, 115 }, 116 }, 117 domain.PaymentFlowActionShowWalletPayment: { 118 Title: "Payment unapproved, wallet", 119 Status: &domain.FlowStatus{ 120 Status: domain.PaymentFlowStatusUnapproved, 121 Action: domain.PaymentFlowActionShowWalletPayment, 122 ActionData: domain.FlowActionData{ 123 WalletDetails: &domain.WalletDetails{ 124 UsedPaymentMethod: "ApplePay", 125 PaymentRequestAPI: domain.PaymentRequestAPI{ 126 Methods: `{"a": "b"}`, 127 }, 128 }, 129 }, 130 }, 131 }, 132 "unknown": { 133 Title: "Payment unapproved, unknown", 134 Status: &domain.FlowStatus{ 135 Status: domain.PaymentFlowStatusUnapproved, 136 Action: "unknown", 137 }, 138 }, 139 } 140 ) 141 142 // Inject dependencies 143 func (g *FakeGateway) Inject() *FakeGateway { 144 g.CartIsCompleted = make(map[string]bool) 145 146 return g 147 } 148 149 // Methods returns all payment gateway methods 150 func (g *FakeGateway) Methods() []domain.Method { 151 result := make([]domain.Method, 0, len(methods)) 152 153 for key, val := range methods { 154 result = append(result, domain.Method{Code: key, Title: val.Title}) 155 } 156 157 return result 158 } 159 160 func (g *FakeGateway) isSupportedPaymentMethod(method string) bool { 161 for _, supportedMethod := range g.Methods() { 162 if supportedMethod.Code == method { 163 return true 164 } 165 } 166 return false 167 } 168 169 // StartFlow starts a new Payment flow 170 func (g *FakeGateway) StartFlow(ctx context.Context, cart *cart.Cart, correlationID string, returnURL *url.URL) (*domain.FlowResult, error) { 171 method := "" 172 // just grab the first method we find and use it to decide between the different use cases 173 for qualifier := range cart.PaymentSelection.CartSplit() { 174 method = qualifier.Method 175 break 176 } 177 178 if !g.isSupportedPaymentMethod(method) { 179 return nil, errors.New("specified method not supported by payment gateway: " + method) 180 } 181 182 return &domain.FlowResult{ 183 Status: domain.FlowStatus{ 184 Status: domain.PaymentFlowStatusUnapproved, 185 }, 186 }, nil 187 188 } 189 190 // FlowStatus returns a payment with a state depending on the supplied payment method 191 func (g *FakeGateway) FlowStatus(ctx context.Context, cart *cart.Cart, correlationID string) (*domain.FlowStatus, error) { 192 methodCode := "" 193 // just grab the first method we find and use it to decide between the different use cases 194 for qualifier := range cart.PaymentSelection.CartSplit() { 195 methodCode = qualifier.Method 196 break 197 } 198 199 if !g.isSupportedPaymentMethod(methodCode) { 200 return nil, errors.New("specified method not supported by payment gateway: " + methodCode) 201 } 202 203 if g.CartIsCompleted[cart.ID] { 204 return &domain.FlowStatus{ 205 Status: domain.PaymentFlowStatusCompleted, 206 }, nil 207 } 208 209 return methods[methodCode].Status, nil 210 } 211 212 // ConfirmResult mark payment as completed 213 func (g *FakeGateway) ConfirmResult(ctx context.Context, cart *cart.Cart, cartPayment *placeorder.Payment) error { 214 g.CartIsCompleted[cart.ID] = true 215 return nil 216 } 217 218 // OrderPaymentFromFlow return fake payment 219 func (g *FakeGateway) OrderPaymentFromFlow(ctx context.Context, cart *cart.Cart, correlationID string) (*placeorder.Payment, error) { 220 return &placeorder.Payment{ 221 Gateway: FakePaymentGateway, 222 Transactions: []placeorder.Transaction{ 223 { 224 TransactionID: correlationID, 225 AdditionalData: nil, 226 AmountPayed: cart.GrandTotal, 227 ValuedAmountPayed: cart.GrandTotal, 228 }, 229 }, 230 RawTransactionData: nil, 231 PaymentID: "", 232 }, nil 233 } 234 235 // CancelOrderPayment does nothing 236 func (g *FakeGateway) CancelOrderPayment(ctx context.Context, cartPayment *placeorder.Payment) error { 237 return nil 238 }