github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/tequilapi/endpoints/pilvytis.go (about) 1 /* 2 * Copyright (C) 2020 The "MysteriumNetwork/node" Authors. 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 package endpoints 19 20 import ( 21 "encoding/json" 22 "strings" 23 24 "github.com/mysteriumnetwork/go-rest/apierror" 25 "github.com/mysteriumnetwork/node/core/location/locationstate" 26 "github.com/mysteriumnetwork/node/identity" 27 "github.com/mysteriumnetwork/node/pilvytis" 28 "github.com/mysteriumnetwork/node/tequilapi/contract" 29 "github.com/mysteriumnetwork/node/tequilapi/utils" 30 "github.com/mysteriumnetwork/payments/exchange" 31 32 "github.com/gin-gonic/gin" 33 ) 34 35 type api interface { 36 GetPaymentGatewayOrder(id identity.Identity, oid string) (*pilvytis.GatewayOrderResponse, error) 37 GetPaymentGatewayOrderInvoice(id identity.Identity, oid string) ([]byte, error) 38 GetPaymentGatewayOrders(id identity.Identity) ([]pilvytis.GatewayOrderResponse, error) 39 GetPaymentGateways(optionsCurrency exchange.Currency) ([]pilvytis.GatewaysResponse, error) 40 GetRegistrationPaymentStatus(id identity.Identity) (*pilvytis.RegistrationPaymentResponse, error) 41 GatewayClientCallback(id identity.Identity, gateway string, payload any) error 42 } 43 44 type paymentsIssuer interface { 45 CreatePaymentGatewayOrder(cgo pilvytis.GatewayOrderRequest) (*pilvytis.GatewayOrderResponse, error) 46 } 47 48 type paymentLocationFallback interface { 49 GetOrigin() locationstate.Location 50 } 51 52 type pilvytisEndpoint struct { 53 api api 54 pt paymentsIssuer 55 lf paymentLocationFallback 56 } 57 58 // NewPilvytisEndpoint returns pilvytis endpoints. 59 func NewPilvytisEndpoint(pil api, pt paymentsIssuer, lf paymentLocationFallback) *pilvytisEndpoint { 60 return &pilvytisEndpoint{ 61 api: pil, 62 pt: pt, 63 lf: lf, 64 } 65 } 66 67 // GetPaymentGateways returns data about supported payment gateways. 68 // 69 // swagger:operation GET /v2/payment-order-gateways Order getPaymentGateways 70 // 71 // --- 72 // summary: Get payment gateway configuration. 73 // description: Returns gateway configuration including supported currencies, minimum amounts, etc. 74 // parameters: 75 // - name: options_currency 76 // in: query 77 // description: Currency for payment order options 78 // type: string 79 // required: false 80 // default: MYST 81 // responses: 82 // 200: 83 // description: List of payment gateways 84 // schema: 85 // type: "array" 86 // items: 87 // "$ref": "#/definitions/GatewaysResponse" 88 // 500: 89 // description: Internal server error 90 // schema: 91 // "$ref": "#/definitions/APIError" 92 func (e *pilvytisEndpoint) GetPaymentGateways(c *gin.Context) { 93 optionsCurrency := exchange.Currency(strings.ToUpper(c.DefaultQuery("options_currency", "MYST"))) 94 resp, err := e.api.GetPaymentGateways(optionsCurrency) 95 if err != nil { 96 utils.ForwardError(c, err, apierror.Internal("Failed to list payment gateways", contract.ErrCodePaymentListGateways)) 97 return 98 } 99 100 utils.WriteAsJSON(contract.ToGatewaysReponse(resp), c.Writer) 101 } 102 103 // GetPaymentGatewayOrders returns a list of payment orders. 104 // 105 // swagger:operation GET /v2/identities/{id}/payment-order Order getPaymentGatewayOrders 106 // 107 // --- 108 // summary: Get all orders for identity 109 // description: Gets all orders for a given identity from the pilvytis service 110 // parameters: 111 // - name: id 112 // in: path 113 // description: Identity for which to get orders 114 // type: string 115 // required: true 116 // responses: 117 // 200: 118 // description: List of payment orders 119 // schema: 120 // type: "array" 121 // items: 122 // "$ref": "#/definitions/PaymentOrderResponse" 123 // 500: 124 // description: Internal server error 125 // schema: 126 // "$ref": "#/definitions/APIError" 127 func (e *pilvytisEndpoint) GetPaymentGatewayOrders(c *gin.Context) { 128 resp, err := e.api.GetPaymentGatewayOrders(identity.FromAddress(c.Param("id"))) 129 if err != nil { 130 utils.ForwardError(c, err, apierror.Internal("Failed to list orders", contract.ErrCodePaymentList)) 131 return 132 } 133 134 utils.WriteAsJSON(contract.NewPaymentOrdersResponse(resp), c.Writer) 135 } 136 137 // GetPaymentGatewayOrder returns a payment order which maches a given ID and identity. 138 // 139 // swagger:operation GET /v2/identities/{id}/payment-order/{order_id} Order getPaymentGatewayOrder 140 // 141 // --- 142 // summary: Get order 143 // description: Gets an order for a given identity and order id combo from the pilvytis service 144 // parameters: 145 // - name: id 146 // in: path 147 // description: Identity for which to get an order 148 // type: string 149 // required: true 150 // - name: order_id 151 // in: path 152 // description: Order id 153 // type: integer 154 // required: true 155 // responses: 156 // 200: 157 // description: Order object 158 // schema: 159 // "$ref": "#/definitions/PaymentOrderResponse" 160 // 500: 161 // description: Internal server error 162 // schema: 163 // "$ref": "#/definitions/APIError" 164 func (e *pilvytisEndpoint) GetPaymentGatewayOrder(c *gin.Context) { 165 resp, err := e.api.GetPaymentGatewayOrder( 166 identity.FromAddress(c.Param("id")), 167 c.Param("order_id"), 168 ) 169 if err != nil { 170 utils.ForwardError(c, err, apierror.Internal("Failed to get payment order", contract.ErrCodePaymentGet)) 171 return 172 } 173 174 utils.WriteAsJSON(contract.NewPaymentOrderResponse(resp), c.Writer) 175 } 176 177 // GetPaymentGatewayOrderInvoice returns an invoice for payment order matching the given ID and identity. 178 // 179 // swagger:operation GET /v2/identities/{id}/payment-order/{order_id}/invoice Order getPaymentGatewayOrderInvoice 180 // 181 // --- 182 // summary: Get invoice 183 // description: Gets an invoice for payment order matching the given ID and identity 184 // parameters: 185 // - name: id 186 // in: path 187 // description: Identity for which to get an order invoice 188 // type: string 189 // required: true 190 // - name: order_id 191 // in: path 192 // description: Order id 193 // type: integer 194 // required: true 195 // responses: 196 // 200: 197 // description: Invoice PDF (binary) 198 // 500: 199 // description: Internal server error 200 // schema: 201 // "$ref": "#/definitions/APIError" 202 func (e *pilvytisEndpoint) GetPaymentGatewayOrderInvoice(c *gin.Context) { 203 resp, err := e.api.GetPaymentGatewayOrderInvoice( 204 identity.FromAddress(c.Param("id")), 205 c.Param("order_id"), 206 ) 207 if err != nil { 208 utils.ForwardError(c, err, apierror.Internal("Failed to get invoice", contract.ErrCodePaymentGetInvoice)) 209 return 210 } 211 212 c.Data(200, "application/pdf", resp) 213 } 214 215 // CreatePaymentGatewayOrder creates a new payment order. 216 // 217 // swagger:operation POST /v2/identities/{id}/{gw}/payment-order Order createPaymentGatewayOrder 218 // 219 // --- 220 // summary: Create order 221 // description: Takes the given data and tries to create a new payment order in the pilvytis service. 222 // parameters: 223 // - name: id 224 // in: path 225 // description: Identity for which to create an order 226 // type: string 227 // required: true 228 // - name: gw 229 // in: path 230 // description: Gateway for which a payment order is created 231 // type: string 232 // required: true 233 // - in: body 234 // name: body 235 // description: Required data to create a new order 236 // schema: 237 // $ref: "#/definitions/PaymentOrderRequest" 238 // responses: 239 // 200: 240 // description: Payment order 241 // schema: 242 // "$ref": "#/definitions/PaymentOrderResponse" 243 // 500: 244 // description: Internal server error 245 // schema: 246 // "$ref": "#/definitions/APIError" 247 func (e *pilvytisEndpoint) CreatePaymentGatewayOrder(c *gin.Context) { 248 var req contract.PaymentOrderRequest 249 if err := json.NewDecoder(c.Request.Body).Decode(&req); err != nil { 250 c.Error(apierror.ParseFailed()) 251 return 252 } 253 254 rid := identity.FromAddress(c.Param("id")) 255 256 resp, err := e.pt.CreatePaymentGatewayOrder(req.GatewayOrderRequest(rid, c.Param("gw"))) 257 if err != nil { 258 utils.ForwardError(c, err, apierror.Internal("Failed to create payment order", contract.ErrCodePaymentCreate)) 259 return 260 } 261 262 utils.WriteAsJSON(contract.NewPaymentOrderResponse(resp), c.Writer) 263 } 264 265 // GetRegistrationPaymentStatus returns a whether a registration order has been paid. 266 // 267 // swagger:operation GET /v2/identities/{id}/registration-payment Order getRegistrationPaymentStatus 268 // 269 // --- 270 // summary: Check for registration payment 271 // description: Checks if a registration payment order for an identity has been paid in pilvytis. 272 // parameters: 273 // - name: id 274 // in: path 275 // description: Identity for which to check 276 // type: string 277 // required: true 278 // responses: 279 // 200: 280 // description: Registration order status 281 // schema: 282 // "$ref": "#/definitions/RegistrationPaymentResponse" 283 // 500: 284 // description: Internal server error 285 // schema: 286 // "$ref": "#/definitions/APIError" 287 func (e *pilvytisEndpoint) GetRegistrationPaymentStatus(c *gin.Context) { 288 resp, err := e.api.GetRegistrationPaymentStatus(identity.FromAddress(c.Param("id"))) 289 if err != nil { 290 utils.ForwardError(c, err, apierror.Internal("Failed to get registration payment status", contract.ErrCodePaymentList)) 291 return 292 } 293 294 utils.WriteAsJSON(contract.NewRegistrationPaymentResponse(resp), c.Writer) 295 } 296 297 // AddRoutesForPilvytis adds the pilvytis routers to the given router. 298 func AddRoutesForPilvytis(pilvytis api, pt paymentsIssuer, lf paymentLocationFallback) func(*gin.Engine) error { 299 pil := NewPilvytisEndpoint(pilvytis, pt, lf) 300 return func(e *gin.Engine) error { 301 idGroupV2 := e.Group("/v2/identities") 302 { 303 idGroupV2.POST("/:id/:gw/payment-order", pil.CreatePaymentGatewayOrder) 304 idGroupV2.GET("/:id/payment-order/:order_id", pil.GetPaymentGatewayOrder) 305 idGroupV2.GET("/:id/payment-order/:order_id/invoice", pil.GetPaymentGatewayOrderInvoice) 306 idGroupV2.GET("/:id/payment-order", pil.GetPaymentGatewayOrders) 307 idGroupV2.GET("/:id/registration-payment", pil.GetRegistrationPaymentStatus) 308 } 309 e.GET("/v2/payment-order-gateways", pil.GetPaymentGateways) 310 return nil 311 } 312 }