Rename config vars. Add widget holder template and endpoint to serve it. Add dockerfile
This commit is contained in:
24
Dockerfile
Normal file
24
Dockerfile
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
FROM golang:1.26-alpine3.23 AS build
|
||||||
|
|
||||||
|
WORKDIR /payoutsbuild
|
||||||
|
|
||||||
|
RUN apk add --update --no-cache ca-certificates git
|
||||||
|
|
||||||
|
ENV GOBIN=/payoutsbuild/bin
|
||||||
|
|
||||||
|
ADD . /payoutsbuild
|
||||||
|
|
||||||
|
RUN cd /payoutsbuild && \
|
||||||
|
go mod download && \
|
||||||
|
go build ./cmd/...
|
||||||
|
|
||||||
|
FROM alpine:3.23
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY --from=build /payoutsbuild/payouts /app/
|
||||||
|
COPY --from=build /payoutsbuild/config/payouts.properties /app/
|
||||||
|
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
ENTRYPOINT [ "/app/payouts" ]
|
||||||
@@ -150,8 +150,8 @@
|
|||||||
| YooKassa.Test | Enable test mode | false |
|
| YooKassa.Test | Enable test mode | false |
|
||||||
| YooKassa.ApiBaseKey | YooKassa base API key | (empty) |
|
| YooKassa.ApiBaseKey | YooKassa base API key | (empty) |
|
||||||
| YooKassa.ApiBaseSecret | YooKassa base API secret | (empty) |
|
| YooKassa.ApiBaseSecret | YooKassa base API secret | (empty) |
|
||||||
| YooKassa.ApiPaymentKey | YooKassa payment API key | (empty) |
|
| YooKassa.ApiPayoutKey | YooKassa payout API key | (empty) |
|
||||||
| YooKassa.ApiPaymentSecret | YooKassa payment API secret | (empty) |
|
| YooKassa.ApiPayoutSecret | YooKassa payout API secret | (empty) |
|
||||||
| YooKassa.BaseUrl | YooKassa API base URL | https://api.yookassa.ru/v3 |
|
| YooKassa.BaseUrl | YooKassa API base URL | https://api.yookassa.ru/v3 |
|
||||||
| YooKassa.Timeout | Request timeout | 2s |
|
| YooKassa.Timeout | Request timeout | 2s |
|
||||||
| YooKassa.CheckAllowedCallbackAddress | Check callback IP addresses | true |
|
| YooKassa.CheckAllowedCallbackAddress | Check callback IP addresses | true |
|
||||||
|
|||||||
@@ -55,8 +55,10 @@ YooKassa.AllowedCallbackSubnets = 185.71.76.0/27,185.71.77.0/27,77.75.153.0/25,7
|
|||||||
# Base API key/secret
|
# Base API key/secret
|
||||||
YooKassa.ApiBaseKey =
|
YooKassa.ApiBaseKey =
|
||||||
YooKassa.ApiBaseSecret =
|
YooKassa.ApiBaseSecret =
|
||||||
# Payments API key/secret
|
# Payouts API key/secret
|
||||||
YooKassa.ApiPaymentKey =
|
YooKassa.ApiPayoutKey =
|
||||||
YooKassa.ApiPaymentSecret =
|
YooKassa.ApiPayoutSecret =
|
||||||
# Timeout to process yookassa callback
|
# Timeout to process yookassa callback
|
||||||
YooKassa.CallbackProcessTimeout = 1s
|
YooKassa.CallbackProcessTimeout = 1s
|
||||||
|
# Widget version
|
||||||
|
YooKassa.WidgetVersion = 3.1.0
|
||||||
|
|||||||
@@ -156,8 +156,8 @@ variables. Variable names are the uppercased property key with `.` replaced by `
|
|||||||
| `DATABASE_CONNECTION` | `Database.Connection` |
|
| `DATABASE_CONNECTION` | `Database.Connection` |
|
||||||
| `YOOKASSA_APIBASEKEY` | `YooKassa.ApiBaseKey` |
|
| `YOOKASSA_APIBASEKEY` | `YooKassa.ApiBaseKey` |
|
||||||
| `YOOKASSA_APIBASESECRET` | `YooKassa.ApiBaseSecret` |
|
| `YOOKASSA_APIBASESECRET` | `YooKassa.ApiBaseSecret` |
|
||||||
| `YOOKASSA_APIPAYMENTKEY` | `YooKassa.ApiPaymentKey` |
|
| `YOOKASSA_APIPAYOUTKEY` | `YooKassa.ApiPayoutKey` |
|
||||||
| `YOOKASSA_APIPAYMENTSECRET` | `YooKassa.ApiPaymentSecret` |
|
| `YOOKASSA_APIPAYOUTSECRET` | `YooKassa.ApiPayoutSecret` |
|
||||||
|
|
||||||
Provide secrets at install/upgrade time:
|
Provide secrets at install/upgrade time:
|
||||||
|
|
||||||
@@ -166,8 +166,8 @@ helm install payouts ./helm \
|
|||||||
--set secrets.DATABASE_CONNECTION="host=127.0.0.1 user=app password=s3cr3t dbname=payouts port=5432 sslmode=disable" \
|
--set secrets.DATABASE_CONNECTION="host=127.0.0.1 user=app password=s3cr3t dbname=payouts port=5432 sslmode=disable" \
|
||||||
--set secrets.YOOKASSA_APIBASEKEY="<key>" \
|
--set secrets.YOOKASSA_APIBASEKEY="<key>" \
|
||||||
--set secrets.YOOKASSA_APIBASESECRET="<secret>" \
|
--set secrets.YOOKASSA_APIBASESECRET="<secret>" \
|
||||||
--set secrets.YOOKASSA_APIPAYMENTKEY="<key>" \
|
--set secrets.YOOKASSA_APIPAYOUTKEY="<key>" \
|
||||||
--set secrets.YOOKASSA_APIPAYMENTSECRET="<secret>"
|
--set secrets.YOOKASSA_APIPAYOUTSECRET="<secret>"
|
||||||
```
|
```
|
||||||
|
|
||||||
Or keep them in a separate values file that is **not committed to version control**:
|
Or keep them in a separate values file that is **not committed to version control**:
|
||||||
@@ -180,11 +180,11 @@ Example `secrets.values.yaml`:
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
secrets:
|
secrets:
|
||||||
DATABASE_CONNECTION: "host=127.0.0.1 user=app password=s3cr3t dbname=payouts port=5432 sslmode=disable"
|
DATABASE_CONNECTION: "host=127.0.0.1 user=payouts password=password dbname=payouts port=5432 sslmode=disable"
|
||||||
YOOKASSA_APIBASEKEY: "<key>"
|
YOOKASSA_APIBASEKEY: "<key>"
|
||||||
YOOKASSA_APIBASESECRET: "<secret>"
|
YOOKASSA_APIBASESECRET: "<secret>"
|
||||||
YOOKASSA_APIPAYMENTKEY: "<key>"
|
YOOKASSA_APIPAYOUTKEY: "<key>"
|
||||||
YOOKASSA_APIPAYMENTSECRET: "<secret>"
|
YOOKASSA_APIPAYOUTSECRET: "<secret>"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Ingress example
|
### Ingress example
|
||||||
|
|||||||
@@ -31,15 +31,15 @@
|
|||||||
3. Secret environment variables are injected from Secret {{ include "payouts.fullname" . }}:
|
3. Secret environment variables are injected from Secret {{ include "payouts.fullname" . }}:
|
||||||
{{- end }}
|
{{- end }}
|
||||||
DATABASE_CONNECTION, YOOKASSA_APIBASEKEY, YOOKASSA_APIBASESECRET,
|
DATABASE_CONNECTION, YOOKASSA_APIBASEKEY, YOOKASSA_APIBASESECRET,
|
||||||
YOOKASSA_APIPAYMENTKEY, YOOKASSA_APIPAYMENTSECRET
|
YOOKASSA_APIPAYOUTKEY, YOOKASSA_APIPAYOUTSECRET
|
||||||
|
|
||||||
Before deploying to production, populate these values:
|
Before deploying to production, populate these values:
|
||||||
helm upgrade {{ .Release.Name }} ./helm \
|
helm upgrade {{ .Release.Name }} ./helm \
|
||||||
--set secrets.DATABASE_CONNECTION="host=... dbname=..." \
|
--set secrets.DATABASE_CONNECTION="host=... dbname=..." \
|
||||||
--set secrets.YOOKASSA_APIBASEKEY="<key>" \
|
--set secrets.YOOKASSA_APIBASEKEY="<key>" \
|
||||||
--set secrets.YOOKASSA_APIBASESECRET="<secret>" \
|
--set secrets.YOOKASSA_APIBASESECRET="<secret>" \
|
||||||
--set secrets.YOOKASSA_APIPAYMENTKEY="<key>" \
|
--set secrets.YOOKASSA_APIPAYOUTKEY="<key>" \
|
||||||
--set secrets.YOOKASSA_APIPAYMENTSECRET="<secret>"
|
--set secrets.YOOKASSA_APIPAYOUTSECRET="<secret>"
|
||||||
|
|
||||||
Or use a separate values file that is not committed to version control:
|
Or use a separate values file that is not committed to version control:
|
||||||
helm upgrade {{ .Release.Name }} ./helm -f secrets.values.yaml
|
helm upgrade {{ .Release.Name }} ./helm -f secrets.values.yaml
|
||||||
|
|||||||
@@ -101,5 +101,5 @@ secrets:
|
|||||||
DATABASE_CONNECTION: ""
|
DATABASE_CONNECTION: ""
|
||||||
YOOKASSA_APIBASEKEY: ""
|
YOOKASSA_APIBASEKEY: ""
|
||||||
YOOKASSA_APIBASESECRET: ""
|
YOOKASSA_APIBASESECRET: ""
|
||||||
YOOKASSA_APIPAYMENTKEY: ""
|
YOOKASSA_APIPAYOUTKEY: ""
|
||||||
YOOKASSA_APIPAYMENTSECRET: ""
|
YOOKASSA_APIPAYOUTSECRET: ""
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import (
|
|||||||
"payouts/internal/api/payout"
|
"payouts/internal/api/payout"
|
||||||
"payouts/internal/api/user"
|
"payouts/internal/api/user"
|
||||||
"payouts/internal/api/version"
|
"payouts/internal/api/version"
|
||||||
|
"payouts/internal/api/widget"
|
||||||
appConfig "payouts/internal/config"
|
appConfig "payouts/internal/config"
|
||||||
"payouts/internal/service/monitoring"
|
"payouts/internal/service/monitoring"
|
||||||
)
|
)
|
||||||
@@ -25,6 +26,7 @@ var Module = fx.Options(
|
|||||||
health.Module,
|
health.Module,
|
||||||
payout.Module,
|
payout.Module,
|
||||||
version.Module,
|
version.Module,
|
||||||
|
widget.Module,
|
||||||
monitoring.Module,
|
monitoring.Module,
|
||||||
|
|
||||||
fx.Invoke(RegisterRoutes),
|
fx.Invoke(RegisterRoutes),
|
||||||
@@ -41,8 +43,9 @@ type Params struct {
|
|||||||
|
|
||||||
PayoutHandler payout.Handler
|
PayoutHandler payout.Handler
|
||||||
UserHandler user.Handler
|
UserHandler user.Handler
|
||||||
Version version.Handler
|
|
||||||
HealthHandler health.Handler
|
HealthHandler health.Handler
|
||||||
|
Version version.Handler
|
||||||
|
Widget widget.Handler
|
||||||
|
|
||||||
Metrics monitoring.Metrics
|
Metrics monitoring.Metrics
|
||||||
}
|
}
|
||||||
@@ -77,6 +80,9 @@ func RegisterRoutes(p Params, lc fx.Lifecycle) {
|
|||||||
payoutRouter.HandleFunc(payout.CreateRoute, p.PayoutHandler.PayoutCreate).Methods(http.MethodPost)
|
payoutRouter.HandleFunc(payout.CreateRoute, p.PayoutHandler.PayoutCreate).Methods(http.MethodPost)
|
||||||
payoutRouter.HandleFunc(payout.CallbackRoute, p.PayoutHandler.PayoutCallback).Methods(http.MethodPost)
|
payoutRouter.HandleFunc(payout.CallbackRoute, p.PayoutHandler.PayoutCallback).Methods(http.MethodPost)
|
||||||
|
|
||||||
|
// Widget endpoint
|
||||||
|
router.HandleFunc(widget.WidgetPage, p.Widget.WidgetHandler).Methods(http.MethodGet)
|
||||||
|
|
||||||
// collect api metrics
|
// collect api metrics
|
||||||
apiRouter.Use(p.Metrics.GetMiddleware())
|
apiRouter.Use(p.Metrics.GetMiddleware())
|
||||||
|
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ func (p *payoutHandler) GetSbpBanks(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PaymentCreate implements [Handler].
|
// PayoutCreate implements [Handler].
|
||||||
func (p *payoutHandler) PayoutCreate(w http.ResponseWriter, r *http.Request) {
|
func (p *payoutHandler) PayoutCreate(w http.ResponseWriter, r *http.Request) {
|
||||||
defer r.Body.Close()
|
defer r.Body.Close()
|
||||||
|
|
||||||
@@ -203,7 +203,7 @@ func (p *payoutHandler) delayedPayoutUpdate(ctx context.Context, payoutData *yoo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PaymentCallback implements [Handler].
|
// PayoutCallback implements [Handler].
|
||||||
func (p *payoutHandler) PayoutCallback(w http.ResponseWriter, r *http.Request) {
|
func (p *payoutHandler) PayoutCallback(w http.ResponseWriter, r *http.Request) {
|
||||||
// todo: check also the X-real-ip and/or X-Forwarded-For
|
// todo: check also the X-real-ip and/or X-Forwarded-For
|
||||||
if p.yookassaConf.CheckAllowedCallbackAddress && !p.checkAllowedIpCallback(r.RemoteAddr) {
|
if p.yookassaConf.CheckAllowedCallbackAddress && !p.checkAllowedIpCallback(r.RemoteAddr) {
|
||||||
|
|||||||
9
internal/api/widget/module.go
Normal file
9
internal/api/widget/module.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package widget
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go.uber.org/fx"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Module = fx.Options(
|
||||||
|
fx.Provide(NewWidgetHandler),
|
||||||
|
)
|
||||||
55
internal/api/widget/widget_handler.go
Normal file
55
internal/api/widget/widget_handler.go
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
package widget
|
||||||
|
|
||||||
|
import (
|
||||||
|
"html/template"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"go.uber.org/fx"
|
||||||
|
|
||||||
|
"payouts/internal/service/yookassa"
|
||||||
|
yookassaConf "payouts/internal/service/yookassa/config"
|
||||||
|
"payouts/internal/templates"
|
||||||
|
)
|
||||||
|
|
||||||
|
const WidgetPage = "/payout/widget"
|
||||||
|
|
||||||
|
type Handler interface {
|
||||||
|
WidgetHandler(http.ResponseWriter, *http.Request)
|
||||||
|
}
|
||||||
|
|
||||||
|
type widgetHandler struct {
|
||||||
|
template *template.Template
|
||||||
|
config yookassaConf.YooKassa
|
||||||
|
}
|
||||||
|
|
||||||
|
// Params represents the module input params
|
||||||
|
type Params struct {
|
||||||
|
fx.In
|
||||||
|
|
||||||
|
YookassaService yookassa.Service
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWidgetHandler(p Params) (Handler, error) {
|
||||||
|
return &widgetHandler{
|
||||||
|
template: templates.Templates,
|
||||||
|
config: p.YookassaService.GetConfig(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WidgetHandler renders the payouts widget page
|
||||||
|
func (h *widgetHandler) WidgetHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
data := struct {
|
||||||
|
ApiPayoutKey string
|
||||||
|
WidgetVersion string
|
||||||
|
}{
|
||||||
|
ApiPayoutKey: h.config.ApiPayoutKey,
|
||||||
|
WidgetVersion: h.config.WidgetVersion,
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||||
|
err := h.template.ExecuteTemplate(w, "payouts-widget.html", data)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "internal error", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,8 @@ type PayoutType int64
|
|||||||
const (
|
const (
|
||||||
TypeSBP PayoutType = iota
|
TypeSBP PayoutType = iota
|
||||||
TypeYooMoney
|
TypeYooMoney
|
||||||
|
TypeCard
|
||||||
|
TypeCardWidget
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r PayoutType) String() string {
|
func (r PayoutType) String() string {
|
||||||
@@ -18,6 +20,10 @@ func (r PayoutType) String() string {
|
|||||||
return "spb"
|
return "spb"
|
||||||
case TypeYooMoney:
|
case TypeYooMoney:
|
||||||
return "yoo_money"
|
return "yoo_money"
|
||||||
|
case TypeCard:
|
||||||
|
return "bank_card"
|
||||||
|
case TypeCardWidget:
|
||||||
|
return "widget"
|
||||||
}
|
}
|
||||||
return "unknown"
|
return "unknown"
|
||||||
}
|
}
|
||||||
@@ -33,8 +39,12 @@ func (r *PayoutType) UnmarshalText(text []byte) (err error) {
|
|||||||
*r = TypeSBP
|
*r = TypeSBP
|
||||||
case "yoo_money":
|
case "yoo_money":
|
||||||
*r = TypeYooMoney
|
*r = TypeYooMoney
|
||||||
|
case "bank_card":
|
||||||
|
*r = TypeCard
|
||||||
|
case "widget":
|
||||||
|
*r = TypeCardWidget
|
||||||
default:
|
default:
|
||||||
err = fmt.Errorf("invalid payment type: %s", s)
|
err = fmt.Errorf("invalid payout type: %s", s)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -83,7 +93,7 @@ func (r *PayoutStatus) UnmarshalText(text []byte) (err error) {
|
|||||||
case "failed":
|
case "failed":
|
||||||
*r = StatusFailed
|
*r = StatusFailed
|
||||||
default:
|
default:
|
||||||
err = fmt.Errorf("invalid payment type: %s", s)
|
err = fmt.Errorf("invalid payout type: %s", s)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -96,8 +106,10 @@ type SBPBank struct {
|
|||||||
|
|
||||||
type PayoutReq struct {
|
type PayoutReq struct {
|
||||||
PayoutType PayoutType `json:"payout_type"`
|
PayoutType PayoutType `json:"payout_type"`
|
||||||
|
PayoutToken string `json:"payout_token"`
|
||||||
AccountNumber string `json:"account_number"`
|
AccountNumber string `json:"account_number"`
|
||||||
BankID string `json:"bank_id"`
|
BankID string `json:"bank_id"`
|
||||||
|
CardNumber string `json:"card_number"`
|
||||||
Amount float32 `json:"amount"`
|
Amount float32 `json:"amount"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,9 @@ type YooKassa struct {
|
|||||||
|
|
||||||
ApiBaseKey string
|
ApiBaseKey string
|
||||||
ApiBaseSecret string
|
ApiBaseSecret string
|
||||||
ApiPaymentKey string
|
ApiPayoutKey string
|
||||||
ApiPaymentSecret string
|
ApiPayoutSecret string
|
||||||
|
WidgetVersion string
|
||||||
|
|
||||||
CallbackProcessTimeout time.Duration
|
CallbackProcessTimeout time.Duration
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ type Metadata map[string]any
|
|||||||
|
|
||||||
type PayoutRequest struct {
|
type PayoutRequest struct {
|
||||||
Amount Amount `json:"amount"`
|
Amount Amount `json:"amount"`
|
||||||
PayoutDestinationData PayoutDestination `json:"payout_destination_data"`
|
PayoutToken string `json:"payout_token,omitempty"`
|
||||||
|
PayoutDestinationData PayoutDestination `json:"payout_destination_data,omitzero"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Metadata Metadata `json:"metadata"`
|
Metadata Metadata `json:"metadata"`
|
||||||
Test bool `json:"test"`
|
Test bool `json:"test"`
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ type yookassaService struct {
|
|||||||
func NewYookassaService(conf config.YooKassa) (Service, error) {
|
func NewYookassaService(conf config.YooKassa) (Service, error) {
|
||||||
client := resty.New()
|
client := resty.New()
|
||||||
client.SetBaseURL(conf.BaseUrl)
|
client.SetBaseURL(conf.BaseUrl)
|
||||||
client.SetBasicAuth(conf.ApiPaymentKey, conf.ApiPaymentSecret)
|
client.SetBasicAuth(conf.ApiPayoutKey, conf.ApiPayoutSecret)
|
||||||
client.SetTimeout(conf.Timeout)
|
client.SetTimeout(conf.Timeout)
|
||||||
|
|
||||||
if conf.Retry.Enabled {
|
if conf.Retry.Enabled {
|
||||||
@@ -110,10 +110,23 @@ func (y *yookassaService) CreatePayout(req models.PayoutReq, userSession *orm.Us
|
|||||||
|
|
||||||
switch req.PayoutType {
|
switch req.PayoutType {
|
||||||
case models.TypeSBP:
|
case models.TypeSBP:
|
||||||
yReq.PayoutDestinationData.Phone = userSession.Phone
|
yReq.PayoutDestinationData = PayoutDestination{
|
||||||
yReq.PayoutDestinationData.BankID = req.BankID
|
Phone: userSession.Phone,
|
||||||
|
BankID: req.BankID,
|
||||||
|
}
|
||||||
|
|
||||||
case models.TypeYooMoney:
|
case models.TypeYooMoney:
|
||||||
yReq.PayoutDestinationData.AccountNumber = req.AccountNumber
|
yReq.PayoutDestinationData.AccountNumber = req.AccountNumber
|
||||||
|
|
||||||
|
case models.TypeCard:
|
||||||
|
yReq.PayoutDestinationData.Card = Card{
|
||||||
|
Number: req.CardNumber,
|
||||||
|
}
|
||||||
|
|
||||||
|
case models.TypeCardWidget:
|
||||||
|
yReq.PayoutToken = req.PayoutToken
|
||||||
|
yReq.PayoutDestinationData = PayoutDestination{}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, errors.New("unsupported payout type")
|
return nil, errors.New("unsupported payout type")
|
||||||
}
|
}
|
||||||
|
|||||||
45
internal/templates/payouts-widget.html
Normal file
45
internal/templates/payouts-widget.html
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Payouts Page</title>
|
||||||
|
<script src="https://yookassa.ru/payouts-data/{{ .WidgetVersion }}/widget.js"></script>
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="payout-form"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Инициализация виджета. Все параметры обязательные.
|
||||||
|
const payoutsData = new window.PayoutsData({
|
||||||
|
type: 'payout',
|
||||||
|
account_id: '{{ .ApiPayoutKey }}', // Идентификатор шлюза (agentId в личном кабинете)
|
||||||
|
success_callback: function(data) {
|
||||||
|
// https://yookassa.ru/developers/payouts/making-payouts/bank-card/using-payout-widget/implementing-widget#reference-output-parameters
|
||||||
|
if (window.AndroidCallback) {
|
||||||
|
window.AndroidCallback.onWidgetData(JSON.stringify(data));
|
||||||
|
} else if (window.webkit && window.webkit.messageHandlers.iosCallback) {
|
||||||
|
window.webkit.messageHandlers.iosCallback.onWidgetData(JSON.stringify(data));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error_callback: function(error) {
|
||||||
|
// https://yookassa.ru/developers/payouts/making-payouts/bank-card/using-payout-widget/implementing-widget#reference-output-parameters-error
|
||||||
|
if (window.AndroidCallback) {
|
||||||
|
window.AndroidCallback.onWidgetError(JSON.stringify(error));
|
||||||
|
} else if (window.webkit && window.webkit.messageHandlers.iosCallback) {
|
||||||
|
window.webkit.messageHandlers.iosCallback.onWidgetError(JSON.stringify(error));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Отображение формы в контейнере
|
||||||
|
payoutsData.render('payout-form')
|
||||||
|
//Метод возвращает Promise, исполнение которого говорит о полной загрузке формы сбора данных (можно не использовать).
|
||||||
|
.then(() => {
|
||||||
|
//Код, который нужно выполнить после отображения формы.
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
11
internal/templates/templates.go
Normal file
11
internal/templates/templates.go
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package templates
|
||||||
|
|
||||||
|
import (
|
||||||
|
"embed"
|
||||||
|
"html/template"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed *.html
|
||||||
|
var FS embed.FS
|
||||||
|
|
||||||
|
var Templates = template.Must(template.ParseFS(FS, "*.html"))
|
||||||
Reference in New Issue
Block a user