Try to use generated yookassa client (unsuccessful)

This commit is contained in:
2026-03-17 16:37:29 +03:00
parent 35f6dc6ca0
commit 2c19b9c29b
14 changed files with 867 additions and 698 deletions

View File

@@ -9,6 +9,7 @@ import (
"net/http"
"regexp"
"github.com/google/uuid"
"go.uber.org/fx"
"payouts/internal/config"
@@ -124,13 +125,26 @@ func (p *payoutHandler) PayoutCreate(w http.ResponseWriter, r *http.Request) {
return
}
idempotenceKey := uuid.New().String()
payoutModel := &orm.Payout{
User: *userSession,
IdempotenceKey: idempotenceKey,
Type: payoutReq.PayoutType.String(),
Amount: payoutReq.Amount,
Status: orm.StatusCreated,
}
err = p.dbService.CreatePayout(payoutModel, database.WithContext(r.Context()))
slog.Debug(fmt.Sprintf("Received create payload request: %v from user %v", payoutReq, userSession))
err = p.yooKassa.CreatePayout(payoutReq, userSession)
payoutResp, err := p.yooKassa.CreatePayout(payoutReq, userSession, idempotenceKey, yookassa.WithContext(r.Context()))
if err != nil {
slog.Error("Failed to create payout request", slog.String("error", err.Error()))
errResponse("failed to create payout request", err, http.StatusBadRequest)
return
}
encoder := json.NewEncoder(w)
encoder.Encode(payoutResp)
}
// PaymentCallback implements [Handler].

View File

@@ -82,7 +82,7 @@ func (u *userHandler) UserRegister(w http.ResponseWriter, r *http.Request) {
copier.Copy(&ormUser, user)
// todo: add data validation
err = u.dbService.CreateUser(ormUser, database.WithContext(r.Context()))
err = u.dbService.CreateUser(&ormUser, database.WithContext(r.Context()))
if err != nil {
slog.Error("Failed to create user", slog.String("error", err.Error()))
errResponse("failed to create user", err, http.StatusBadRequest)
@@ -114,7 +114,7 @@ func (u *userHandler) UserLogin(w http.ResponseWriter, r *http.Request) {
return
}
ormUser, err := u.dbService.GetUser(orm.User{Phone: user.Phone}, database.WithContext(r.Context()))
ormUser, err := u.dbService.GetUser(&orm.User{Phone: user.Phone}, database.WithContext(r.Context()))
if err != nil {
errResponse("invalid credentials", nil, http.StatusUnauthorized)
return

View File

@@ -46,6 +46,7 @@ type PayoutReq struct {
}
type PayoutResp struct {
Success bool `json:"success"`
Reason string `json:"reason,omitempty"`
Result string `json:"result"`
PayoutID string `json:"payout_id,omitempty"`
ErrorReason string `json:"error_reason,omitempty"`
}

View File

@@ -73,16 +73,33 @@ func (d *dbService) getParams(options ...Optional) *params {
}
// AddUser implements [Service].
func (d *dbService) CreateUser(userModel orm.User, opts ...Optional) error {
func (d *dbService) CreateUser(userModel *orm.User, opts ...Optional) error {
p := d.getParams(opts...)
return gorm.G[orm.User](d.db).Create(p.ctx, &userModel)
return gorm.G[orm.User](d.db).Create(p.ctx, userModel)
}
// GetUser implements [Service].
func (d *dbService) GetUser(userModel orm.User, opts ...Optional) (orm.User, error) {
func (d *dbService) GetUser(userModel *orm.User, opts ...Optional) (orm.User, error) {
p := d.getParams(opts...)
return gorm.G[orm.User](d.db).Where(userModel).First(p.ctx)
}
// GetPayout implements [Service].
func (d *dbService) GetPayout(payoutModel *orm.Payout, opts ...Optional) (orm.Payout, error) {
p := d.getParams(opts...)
return gorm.G[orm.Payout](d.db).Where(payoutModel).First(p.ctx)
}
// CreatePayout implements [Service].
func (d *dbService) CreatePayout(payoutModel *orm.Payout, opts ...Optional) error {
p := d.getParams(opts...)
userResp, err := gorm.G[orm.User](d.db).Where(&userModel).First(p.ctx)
return userResp, err
return gorm.G[orm.Payout](d.db).Create(p.ctx, payoutModel)
}
// UpdatePayout implements [Service].
func (d *dbService) UpdatePayout(payoutModel *orm.Payout, opts ...Optional) error {
// p := d.getParams(opts...)
panic("unimplemented")
}

View File

@@ -25,8 +25,11 @@ func WithContext(ctx context.Context) Optional {
}
type Service interface {
CreateUser(user orm.User, opts ...Optional) error
GetUser(user orm.User, opts ...Optional) (orm.User, error)
CreateUser(user *orm.User, opts ...Optional) error
GetUser(user *orm.User, opts ...Optional) (orm.User, error)
GetPayout(payoutModel *orm.Payout, opts ...Optional) (orm.Payout, error)
CreatePayout(payoutModel *orm.Payout, opts ...Optional) error
UpdatePayout(payoutModel *orm.Payout, opts ...Optional) error
}
// Params represents the module input params

View File

@@ -1,6 +1,60 @@
package orm
import "gorm.io/gorm"
import (
"fmt"
"strings"
"gorm.io/gorm"
)
type PayoutStatus int64
const (
StatusCreated PayoutStatus = iota
StatusCanceled
StatusPending
StatusSucceeded
StatusFailed
)
func (r PayoutStatus) String() string {
switch r {
case StatusCreated:
return "created"
case StatusCanceled:
return "canceled"
case StatusPending:
return "pending"
case StatusSucceeded:
return "succeeded"
case StatusFailed:
return "failed"
}
return "unknown"
}
func (r PayoutStatus) MarshalText() (text []byte, err error) {
return []byte(r.String()), nil
}
func (r *PayoutStatus) UnmarshalText(text []byte) (err error) {
s := strings.ToLower(string(text))
switch s {
case "canceled":
*r = StatusCanceled
case "created":
*r = StatusCreated
case "pending":
*r = StatusPending
case "succeeded":
*r = StatusSucceeded
case "failed":
*r = StatusFailed
default:
err = fmt.Errorf("invalid payment type: %s", s)
}
return err
}
type Payout struct {
gorm.Model
@@ -9,11 +63,12 @@ type Payout struct {
User User
Description string
IdempotenceKey string
PayoutID string
Type string
AccountNumber string
Amount float32
Currency string
Status string
Status PayoutStatus
Test bool
}

View File

@@ -1535,6 +1535,115 @@ func (s *BadRequestType) UnmarshalJSON(data []byte) error {
return s.Decode(d)
}
// Encode implements json.Marshaler.
func (s *BankCard) Encode(e *jx.Encoder) {
e.ObjStart()
s.encodeFields(e)
e.ObjEnd()
}
// encodeFields encodes fields.
func (s *BankCard) encodeFields(e *jx.Encoder) {
{
e.FieldStart("type")
s.Type.Encode(e)
}
{
e.FieldStart("card")
s.Card.Encode(e)
}
}
var jsonFieldsNameOfBankCard = [2]string{
0: "type",
1: "card",
}
// Decode decodes BankCard from json.
func (s *BankCard) Decode(d *jx.Decoder) error {
if s == nil {
return errors.New("invalid: unable to decode BankCard to nil")
}
var requiredBitSet [1]uint8
if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error {
switch string(k) {
case "type":
requiredBitSet[0] |= 1 << 0
if err := func() error {
if err := s.Type.Decode(d); err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"type\"")
}
case "card":
requiredBitSet[0] |= 1 << 1
if err := func() error {
if err := s.Card.Decode(d); err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"card\"")
}
default:
return d.Skip()
}
return nil
}); err != nil {
return errors.Wrap(err, "decode BankCard")
}
// Validate required fields.
var failures []validate.FieldError
for i, mask := range [1]uint8{
0b00000011,
} {
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
// Mask only required fields and check equality to mask using XOR.
//
// If XOR result is not zero, result is not equal to expected, so some fields are missed.
// Bits of fields which would be set are actually bits of missed fields.
missed := bits.OnesCount8(result)
for bitN := 0; bitN < missed; bitN++ {
bitIdx := bits.TrailingZeros8(result)
fieldIdx := i*8 + bitIdx
var name string
if fieldIdx < len(jsonFieldsNameOfBankCard) {
name = jsonFieldsNameOfBankCard[fieldIdx]
} else {
name = strconv.Itoa(fieldIdx)
}
failures = append(failures, validate.FieldError{
Name: name,
Error: validate.ErrFieldRequired,
})
// Reset bit.
result &^= 1 << bitIdx
}
}
}
if len(failures) > 0 {
return &validate.Error{Fields: failures}
}
return nil
}
// MarshalJSON implements stdjson.Marshaler.
func (s *BankCard) MarshalJSON() ([]byte, error) {
e := jx.Encoder{}
s.Encode(&e)
return e.Bytes(), nil
}
// UnmarshalJSON implements stdjson.Unmarshaler.
func (s *BankCard) UnmarshalJSON(data []byte) error {
d := jx.DecodeBytes(data)
return s.Decode(d)
}
// Encode implements json.Marshaler.
func (s *BankCardData) Encode(e *jx.Encoder) {
e.ObjStart()
@@ -28019,9 +28128,15 @@ func (s *PayoutRequest) encodeFields(e *jx.Encoder) {
s.Metadata.Encode(e)
}
}
{
if s.Test.Set {
e.FieldStart("test")
s.Test.Encode(e)
}
}
}
var jsonFieldsNameOfPayoutRequest = [8]string{
var jsonFieldsNameOfPayoutRequest = [9]string{
0: "amount",
1: "payout_destination_data",
2: "payout_token",
@@ -28030,6 +28145,7 @@ var jsonFieldsNameOfPayoutRequest = [8]string{
5: "deal",
6: "personal_data",
7: "metadata",
8: "test",
}
// Decode decodes PayoutRequest from json.
@@ -28037,7 +28153,7 @@ func (s *PayoutRequest) Decode(d *jx.Decoder) error {
if s == nil {
return errors.New("invalid: unable to decode PayoutRequest to nil")
}
var requiredBitSet [1]uint8
var requiredBitSet [2]uint8
if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error {
switch string(k) {
@@ -28128,6 +28244,16 @@ func (s *PayoutRequest) Decode(d *jx.Decoder) error {
}(); err != nil {
return errors.Wrap(err, "decode field \"metadata\"")
}
case "test":
if err := func() error {
s.Test.Reset()
if err := s.Test.Decode(d); err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"test\"")
}
default:
return d.Skip()
}
@@ -28137,8 +28263,9 @@ func (s *PayoutRequest) Decode(d *jx.Decoder) error {
}
// Validate required fields.
var failures []validate.FieldError
for i, mask := range [1]uint8{
for i, mask := range [2]uint8{
0b00000001,
0b00000000,
} {
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
// Mask only required fields and check equality to mask using XOR.
@@ -28304,31 +28431,31 @@ func (s PayoutRequestPayoutDestinationData) Encode(e *jx.Encoder) {
func (s PayoutRequestPayoutDestinationData) encodeFields(e *jx.Encoder) {
switch s.Type {
case PayoutToYooMoneyDestinationDataPayoutRequestPayoutDestinationData:
case YooMoneyPayoutRequestPayoutDestinationData:
e.FieldStart("type")
e.Str("PayoutToYooMoneyDestinationData")
e.Str("yoo_money")
{
s := s.PayoutToYooMoneyDestinationData
s := s.YooMoney
{
e.FieldStart("account_number")
e.Str(s.AccountNumber)
}
}
case PayoutToBankCardDestinationDataPayoutRequestPayoutDestinationData:
case BankCardPayoutRequestPayoutDestinationData:
e.FieldStart("type")
e.Str("PayoutToBankCardDestinationData")
e.Str("bank_card")
{
s := s.PayoutToBankCardDestinationData
s := s.BankCard
{
e.FieldStart("card")
s.Card.Encode(e)
}
}
case PayoutToSbpDestinationDataPayoutRequestPayoutDestinationData:
case SbpPayoutRequestPayoutDestinationData:
e.FieldStart("type")
e.Str("PayoutToSbpDestinationData")
e.Str("sbp")
{
s := s.PayoutToSbpDestinationData
s := s.Sbp
{
e.FieldStart("phone")
e.Str(s.Phone)
@@ -28364,14 +28491,14 @@ func (s *PayoutRequestPayoutDestinationData) Decode(d *jx.Decoder) error {
return err
}
switch typ {
case "PayoutToYooMoneyDestinationData":
s.Type = PayoutToYooMoneyDestinationDataPayoutRequestPayoutDestinationData
case "yoo_money":
s.Type = YooMoneyPayoutRequestPayoutDestinationData
found = true
case "PayoutToBankCardDestinationData":
s.Type = PayoutToBankCardDestinationDataPayoutRequestPayoutDestinationData
case "bank_card":
s.Type = BankCardPayoutRequestPayoutDestinationData
found = true
case "PayoutToSbpDestinationData":
s.Type = PayoutToSbpDestinationDataPayoutRequestPayoutDestinationData
case "sbp":
s.Type = SbpPayoutRequestPayoutDestinationData
found = true
default:
return errors.Errorf("unknown type %s", typ)
@@ -28387,16 +28514,16 @@ func (s *PayoutRequestPayoutDestinationData) Decode(d *jx.Decoder) error {
return errors.New("unable to detect sum type variant")
}
switch s.Type {
case PayoutToYooMoneyDestinationDataPayoutRequestPayoutDestinationData:
if err := s.PayoutToYooMoneyDestinationData.Decode(d); err != nil {
case YooMoneyPayoutRequestPayoutDestinationData:
if err := s.YooMoney.Decode(d); err != nil {
return err
}
case PayoutToBankCardDestinationDataPayoutRequestPayoutDestinationData:
if err := s.PayoutToBankCardDestinationData.Decode(d); err != nil {
case BankCardPayoutRequestPayoutDestinationData:
if err := s.BankCard.Decode(d); err != nil {
return err
}
case PayoutToSbpDestinationDataPayoutRequestPayoutDestinationData:
if err := s.PayoutToSbpDestinationData.Decode(d); err != nil {
case SbpPayoutRequestPayoutDestinationData:
if err := s.Sbp.Decode(d); err != nil {
return err
}
default:
@@ -28729,115 +28856,6 @@ func (s *PayoutStatus) UnmarshalJSON(data []byte) error {
return s.Decode(d)
}
// Encode implements json.Marshaler.
func (s *PayoutToBankCardDestinationData) Encode(e *jx.Encoder) {
e.ObjStart()
s.encodeFields(e)
e.ObjEnd()
}
// encodeFields encodes fields.
func (s *PayoutToBankCardDestinationData) encodeFields(e *jx.Encoder) {
{
e.FieldStart("type")
s.Type.Encode(e)
}
{
e.FieldStart("card")
s.Card.Encode(e)
}
}
var jsonFieldsNameOfPayoutToBankCardDestinationData = [2]string{
0: "type",
1: "card",
}
// Decode decodes PayoutToBankCardDestinationData from json.
func (s *PayoutToBankCardDestinationData) Decode(d *jx.Decoder) error {
if s == nil {
return errors.New("invalid: unable to decode PayoutToBankCardDestinationData to nil")
}
var requiredBitSet [1]uint8
if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error {
switch string(k) {
case "type":
requiredBitSet[0] |= 1 << 0
if err := func() error {
if err := s.Type.Decode(d); err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"type\"")
}
case "card":
requiredBitSet[0] |= 1 << 1
if err := func() error {
if err := s.Card.Decode(d); err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"card\"")
}
default:
return d.Skip()
}
return nil
}); err != nil {
return errors.Wrap(err, "decode PayoutToBankCardDestinationData")
}
// Validate required fields.
var failures []validate.FieldError
for i, mask := range [1]uint8{
0b00000011,
} {
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
// Mask only required fields and check equality to mask using XOR.
//
// If XOR result is not zero, result is not equal to expected, so some fields are missed.
// Bits of fields which would be set are actually bits of missed fields.
missed := bits.OnesCount8(result)
for bitN := 0; bitN < missed; bitN++ {
bitIdx := bits.TrailingZeros8(result)
fieldIdx := i*8 + bitIdx
var name string
if fieldIdx < len(jsonFieldsNameOfPayoutToBankCardDestinationData) {
name = jsonFieldsNameOfPayoutToBankCardDestinationData[fieldIdx]
} else {
name = strconv.Itoa(fieldIdx)
}
failures = append(failures, validate.FieldError{
Name: name,
Error: validate.ErrFieldRequired,
})
// Reset bit.
result &^= 1 << bitIdx
}
}
}
if len(failures) > 0 {
return &validate.Error{Fields: failures}
}
return nil
}
// MarshalJSON implements stdjson.Marshaler.
func (s *PayoutToBankCardDestinationData) MarshalJSON() ([]byte, error) {
e := jx.Encoder{}
s.Encode(&e)
return e.Bytes(), nil
}
// UnmarshalJSON implements stdjson.Unmarshaler.
func (s *PayoutToBankCardDestinationData) UnmarshalJSON(data []byte) error {
d := jx.DecodeBytes(data)
return s.Decode(d)
}
// Encode implements json.Marshaler.
func (s *PayoutToCardDestination) Encode(e *jx.Encoder) {
e.ObjStart()
@@ -29094,134 +29112,6 @@ func (s *PayoutToSbpDestination) UnmarshalJSON(data []byte) error {
return s.Decode(d)
}
// Encode implements json.Marshaler.
func (s *PayoutToSbpDestinationData) Encode(e *jx.Encoder) {
e.ObjStart()
s.encodeFields(e)
e.ObjEnd()
}
// encodeFields encodes fields.
func (s *PayoutToSbpDestinationData) encodeFields(e *jx.Encoder) {
{
e.FieldStart("type")
s.Type.Encode(e)
}
{
e.FieldStart("phone")
e.Str(s.Phone)
}
{
e.FieldStart("bank_id")
e.Str(s.BankID)
}
}
var jsonFieldsNameOfPayoutToSbpDestinationData = [3]string{
0: "type",
1: "phone",
2: "bank_id",
}
// Decode decodes PayoutToSbpDestinationData from json.
func (s *PayoutToSbpDestinationData) Decode(d *jx.Decoder) error {
if s == nil {
return errors.New("invalid: unable to decode PayoutToSbpDestinationData to nil")
}
var requiredBitSet [1]uint8
if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error {
switch string(k) {
case "type":
requiredBitSet[0] |= 1 << 0
if err := func() error {
if err := s.Type.Decode(d); err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"type\"")
}
case "phone":
requiredBitSet[0] |= 1 << 1
if err := func() error {
v, err := d.Str()
s.Phone = string(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"phone\"")
}
case "bank_id":
requiredBitSet[0] |= 1 << 2
if err := func() error {
v, err := d.Str()
s.BankID = string(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"bank_id\"")
}
default:
return d.Skip()
}
return nil
}); err != nil {
return errors.Wrap(err, "decode PayoutToSbpDestinationData")
}
// Validate required fields.
var failures []validate.FieldError
for i, mask := range [1]uint8{
0b00000111,
} {
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
// Mask only required fields and check equality to mask using XOR.
//
// If XOR result is not zero, result is not equal to expected, so some fields are missed.
// Bits of fields which would be set are actually bits of missed fields.
missed := bits.OnesCount8(result)
for bitN := 0; bitN < missed; bitN++ {
bitIdx := bits.TrailingZeros8(result)
fieldIdx := i*8 + bitIdx
var name string
if fieldIdx < len(jsonFieldsNameOfPayoutToSbpDestinationData) {
name = jsonFieldsNameOfPayoutToSbpDestinationData[fieldIdx]
} else {
name = strconv.Itoa(fieldIdx)
}
failures = append(failures, validate.FieldError{
Name: name,
Error: validate.ErrFieldRequired,
})
// Reset bit.
result &^= 1 << bitIdx
}
}
}
if len(failures) > 0 {
return &validate.Error{Fields: failures}
}
return nil
}
// MarshalJSON implements stdjson.Marshaler.
func (s *PayoutToSbpDestinationData) MarshalJSON() ([]byte, error) {
e := jx.Encoder{}
s.Encode(&e)
return e.Bytes(), nil
}
// UnmarshalJSON implements stdjson.Unmarshaler.
func (s *PayoutToSbpDestinationData) UnmarshalJSON(data []byte) error {
d := jx.DecodeBytes(data)
return s.Decode(d)
}
// Encode implements json.Marshaler.
func (s *PayoutToYooMoneyDestination) Encode(e *jx.Encoder) {
e.ObjStart()
@@ -29331,117 +29221,6 @@ func (s *PayoutToYooMoneyDestination) UnmarshalJSON(data []byte) error {
return s.Decode(d)
}
// Encode implements json.Marshaler.
func (s *PayoutToYooMoneyDestinationData) Encode(e *jx.Encoder) {
e.ObjStart()
s.encodeFields(e)
e.ObjEnd()
}
// encodeFields encodes fields.
func (s *PayoutToYooMoneyDestinationData) encodeFields(e *jx.Encoder) {
{
e.FieldStart("type")
s.Type.Encode(e)
}
{
e.FieldStart("account_number")
e.Str(s.AccountNumber)
}
}
var jsonFieldsNameOfPayoutToYooMoneyDestinationData = [2]string{
0: "type",
1: "account_number",
}
// Decode decodes PayoutToYooMoneyDestinationData from json.
func (s *PayoutToYooMoneyDestinationData) Decode(d *jx.Decoder) error {
if s == nil {
return errors.New("invalid: unable to decode PayoutToYooMoneyDestinationData to nil")
}
var requiredBitSet [1]uint8
if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error {
switch string(k) {
case "type":
requiredBitSet[0] |= 1 << 0
if err := func() error {
if err := s.Type.Decode(d); err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"type\"")
}
case "account_number":
requiredBitSet[0] |= 1 << 1
if err := func() error {
v, err := d.Str()
s.AccountNumber = string(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"account_number\"")
}
default:
return d.Skip()
}
return nil
}); err != nil {
return errors.Wrap(err, "decode PayoutToYooMoneyDestinationData")
}
// Validate required fields.
var failures []validate.FieldError
for i, mask := range [1]uint8{
0b00000011,
} {
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
// Mask only required fields and check equality to mask using XOR.
//
// If XOR result is not zero, result is not equal to expected, so some fields are missed.
// Bits of fields which would be set are actually bits of missed fields.
missed := bits.OnesCount8(result)
for bitN := 0; bitN < missed; bitN++ {
bitIdx := bits.TrailingZeros8(result)
fieldIdx := i*8 + bitIdx
var name string
if fieldIdx < len(jsonFieldsNameOfPayoutToYooMoneyDestinationData) {
name = jsonFieldsNameOfPayoutToYooMoneyDestinationData[fieldIdx]
} else {
name = strconv.Itoa(fieldIdx)
}
failures = append(failures, validate.FieldError{
Name: name,
Error: validate.ErrFieldRequired,
})
// Reset bit.
result &^= 1 << bitIdx
}
}
}
if len(failures) > 0 {
return &validate.Error{Fields: failures}
}
return nil
}
// MarshalJSON implements stdjson.Marshaler.
func (s *PayoutToYooMoneyDestinationData) MarshalJSON() ([]byte, error) {
e := jx.Encoder{}
s.Encode(&e)
return e.Bytes(), nil
}
// UnmarshalJSON implements stdjson.Unmarshaler.
func (s *PayoutToYooMoneyDestinationData) UnmarshalJSON(data []byte) error {
d := jx.DecodeBytes(data)
return s.Decode(d)
}
// Encode encodes PayoutsGetInternalServerError as json.
func (s *PayoutsGetInternalServerError) Encode(e *jx.Encoder) {
unwrapped := (*TooManyRequests)(s)
@@ -37969,6 +37748,134 @@ func (s *SavePaymentMethodType) UnmarshalJSON(data []byte) error {
return s.Decode(d)
}
// Encode implements json.Marshaler.
func (s *Sbp) Encode(e *jx.Encoder) {
e.ObjStart()
s.encodeFields(e)
e.ObjEnd()
}
// encodeFields encodes fields.
func (s *Sbp) encodeFields(e *jx.Encoder) {
{
e.FieldStart("type")
s.Type.Encode(e)
}
{
e.FieldStart("phone")
e.Str(s.Phone)
}
{
e.FieldStart("bank_id")
e.Str(s.BankID)
}
}
var jsonFieldsNameOfSbp = [3]string{
0: "type",
1: "phone",
2: "bank_id",
}
// Decode decodes Sbp from json.
func (s *Sbp) Decode(d *jx.Decoder) error {
if s == nil {
return errors.New("invalid: unable to decode Sbp to nil")
}
var requiredBitSet [1]uint8
if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error {
switch string(k) {
case "type":
requiredBitSet[0] |= 1 << 0
if err := func() error {
if err := s.Type.Decode(d); err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"type\"")
}
case "phone":
requiredBitSet[0] |= 1 << 1
if err := func() error {
v, err := d.Str()
s.Phone = string(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"phone\"")
}
case "bank_id":
requiredBitSet[0] |= 1 << 2
if err := func() error {
v, err := d.Str()
s.BankID = string(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"bank_id\"")
}
default:
return d.Skip()
}
return nil
}); err != nil {
return errors.Wrap(err, "decode Sbp")
}
// Validate required fields.
var failures []validate.FieldError
for i, mask := range [1]uint8{
0b00000111,
} {
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
// Mask only required fields and check equality to mask using XOR.
//
// If XOR result is not zero, result is not equal to expected, so some fields are missed.
// Bits of fields which would be set are actually bits of missed fields.
missed := bits.OnesCount8(result)
for bitN := 0; bitN < missed; bitN++ {
bitIdx := bits.TrailingZeros8(result)
fieldIdx := i*8 + bitIdx
var name string
if fieldIdx < len(jsonFieldsNameOfSbp) {
name = jsonFieldsNameOfSbp[fieldIdx]
} else {
name = strconv.Itoa(fieldIdx)
}
failures = append(failures, validate.FieldError{
Name: name,
Error: validate.ErrFieldRequired,
})
// Reset bit.
result &^= 1 << bitIdx
}
}
}
if len(failures) > 0 {
return &validate.Error{Fields: failures}
}
return nil
}
// MarshalJSON implements stdjson.Marshaler.
func (s *Sbp) MarshalJSON() ([]byte, error) {
e := jx.Encoder{}
s.Encode(&e)
return e.Bytes(), nil
}
// UnmarshalJSON implements stdjson.Unmarshaler.
func (s *Sbp) UnmarshalJSON(data []byte) error {
d := jx.DecodeBytes(data)
return s.Decode(d)
}
// Encode encodes SbpBankBic as json.
func (s SbpBankBic) Encode(e *jx.Encoder) {
unwrapped := string(s)
@@ -41949,6 +41856,117 @@ func (s *WebhooksWebhookIDDeleteOK) UnmarshalJSON(data []byte) error {
return s.Decode(d)
}
// Encode implements json.Marshaler.
func (s *YooMoney) Encode(e *jx.Encoder) {
e.ObjStart()
s.encodeFields(e)
e.ObjEnd()
}
// encodeFields encodes fields.
func (s *YooMoney) encodeFields(e *jx.Encoder) {
{
e.FieldStart("type")
s.Type.Encode(e)
}
{
e.FieldStart("account_number")
e.Str(s.AccountNumber)
}
}
var jsonFieldsNameOfYooMoney = [2]string{
0: "type",
1: "account_number",
}
// Decode decodes YooMoney from json.
func (s *YooMoney) Decode(d *jx.Decoder) error {
if s == nil {
return errors.New("invalid: unable to decode YooMoney to nil")
}
var requiredBitSet [1]uint8
if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error {
switch string(k) {
case "type":
requiredBitSet[0] |= 1 << 0
if err := func() error {
if err := s.Type.Decode(d); err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"type\"")
}
case "account_number":
requiredBitSet[0] |= 1 << 1
if err := func() error {
v, err := d.Str()
s.AccountNumber = string(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"account_number\"")
}
default:
return d.Skip()
}
return nil
}); err != nil {
return errors.Wrap(err, "decode YooMoney")
}
// Validate required fields.
var failures []validate.FieldError
for i, mask := range [1]uint8{
0b00000011,
} {
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
// Mask only required fields and check equality to mask using XOR.
//
// If XOR result is not zero, result is not equal to expected, so some fields are missed.
// Bits of fields which would be set are actually bits of missed fields.
missed := bits.OnesCount8(result)
for bitN := 0; bitN < missed; bitN++ {
bitIdx := bits.TrailingZeros8(result)
fieldIdx := i*8 + bitIdx
var name string
if fieldIdx < len(jsonFieldsNameOfYooMoney) {
name = jsonFieldsNameOfYooMoney[fieldIdx]
} else {
name = strconv.Itoa(fieldIdx)
}
failures = append(failures, validate.FieldError{
Name: name,
Error: validate.ErrFieldRequired,
})
// Reset bit.
result &^= 1 << bitIdx
}
}
}
if len(failures) > 0 {
return &validate.Error{Fields: failures}
}
return nil
}
// MarshalJSON implements stdjson.Marshaler.
func (s *YooMoney) MarshalJSON() ([]byte, error) {
e := jx.Encoder{}
s.Encode(&e)
return e.Bytes(), nil
}
// UnmarshalJSON implements stdjson.Unmarshaler.
func (s *YooMoney) UnmarshalJSON(data []byte) error {
d := jx.DecodeBytes(data)
return s.Decode(d)
}
// Encode encodes YooMoneyAccountNumber as json.
func (s YooMoneyAccountNumber) Encode(e *jx.Encoder) {
unwrapped := string(s)

View File

@@ -4,6 +4,7 @@ package gen
import (
"bytes"
"log/slog"
"net/http"
"github.com/go-faster/jx"
@@ -76,6 +77,7 @@ func encodePayoutsPostRequest(
req.Encode(e)
}
encoded := e.Bytes()
slog.Info(string(encoded))
ht.SetBody(r, bytes.NewReader(encoded), contentType)
return nil
}

View File

@@ -684,6 +684,33 @@ func (s *BadRequestType) UnmarshalText(data []byte) error {
}
}
// Merged schema.
// Ref: #/components/schemas/bank_card
type BankCard struct {
Type PayoutDestinationDataType `json:"type"`
Card CardDataForPayoutDestination `json:"card"`
}
// GetType returns the value of Type.
func (s *BankCard) GetType() PayoutDestinationDataType {
return s.Type
}
// GetCard returns the value of Card.
func (s *BankCard) GetCard() CardDataForPayoutDestination {
return s.Card
}
// SetType sets the value of Type.
func (s *BankCard) SetType(val PayoutDestinationDataType) {
s.Type = val
}
// SetCard sets the value of Card.
func (s *BankCard) SetCard(val CardDataForPayoutDestination) {
s.Card = val
}
// Данные банковской карты.
// Ref: #/components/schemas/BankCardData
type BankCardData struct {
@@ -18581,6 +18608,7 @@ type PayoutRequest struct {
// только для разных типов данных.
PersonalData []PayoutsPersonalData `json:"personal_data"`
Metadata OptMetadata `json:"metadata"`
Test OptTest `json:"test"`
}
// GetAmount returns the value of Amount.
@@ -18623,6 +18651,11 @@ func (s *PayoutRequest) GetMetadata() OptMetadata {
return s.Metadata
}
// GetTest returns the value of Test.
func (s *PayoutRequest) GetTest() OptTest {
return s.Test
}
// SetAmount sets the value of Amount.
func (s *PayoutRequest) SetAmount(val PayoutRequestAmount) {
s.Amount = val
@@ -18663,6 +18696,11 @@ func (s *PayoutRequest) SetMetadata(val OptMetadata) {
s.Metadata = val
}
// SetTest sets the value of Test.
func (s *PayoutRequest) SetTest(val OptTest) {
s.Test = val
}
// Сумма в выбранной валюте.
type PayoutRequestAmount struct {
// Сумма в выбранной валюте. Всегда дробное значение.
@@ -18696,9 +18734,9 @@ func (s *PayoutRequestAmount) SetCurrency(val CurrencyCode) {
// PayoutRequestPayoutDestinationData represents sum type.
type PayoutRequestPayoutDestinationData struct {
Type PayoutRequestPayoutDestinationDataType // switch on this field
PayoutToYooMoneyDestinationData PayoutToYooMoneyDestinationData
PayoutToBankCardDestinationData PayoutToBankCardDestinationData
PayoutToSbpDestinationData PayoutToSbpDestinationData
YooMoney YooMoney
BankCard BankCard
Sbp Sbp
}
// PayoutRequestPayoutDestinationDataType is oneOf type of PayoutRequestPayoutDestinationData.
@@ -18706,86 +18744,86 @@ type PayoutRequestPayoutDestinationDataType string
// Possible values for PayoutRequestPayoutDestinationDataType.
const (
PayoutToYooMoneyDestinationDataPayoutRequestPayoutDestinationData PayoutRequestPayoutDestinationDataType = "PayoutToYooMoneyDestinationData"
PayoutToBankCardDestinationDataPayoutRequestPayoutDestinationData PayoutRequestPayoutDestinationDataType = "PayoutToBankCardDestinationData"
PayoutToSbpDestinationDataPayoutRequestPayoutDestinationData PayoutRequestPayoutDestinationDataType = "PayoutToSbpDestinationData"
YooMoneyPayoutRequestPayoutDestinationData PayoutRequestPayoutDestinationDataType = "yoo_money"
BankCardPayoutRequestPayoutDestinationData PayoutRequestPayoutDestinationDataType = "bank_card"
SbpPayoutRequestPayoutDestinationData PayoutRequestPayoutDestinationDataType = "sbp"
)
// IsPayoutToYooMoneyDestinationData reports whether PayoutRequestPayoutDestinationData is PayoutToYooMoneyDestinationData.
func (s PayoutRequestPayoutDestinationData) IsPayoutToYooMoneyDestinationData() bool {
return s.Type == PayoutToYooMoneyDestinationDataPayoutRequestPayoutDestinationData
// IsYooMoney reports whether PayoutRequestPayoutDestinationData is YooMoney.
func (s PayoutRequestPayoutDestinationData) IsYooMoney() bool {
return s.Type == YooMoneyPayoutRequestPayoutDestinationData
}
// IsPayoutToBankCardDestinationData reports whether PayoutRequestPayoutDestinationData is PayoutToBankCardDestinationData.
func (s PayoutRequestPayoutDestinationData) IsPayoutToBankCardDestinationData() bool {
return s.Type == PayoutToBankCardDestinationDataPayoutRequestPayoutDestinationData
// IsBankCard reports whether PayoutRequestPayoutDestinationData is BankCard.
func (s PayoutRequestPayoutDestinationData) IsBankCard() bool {
return s.Type == BankCardPayoutRequestPayoutDestinationData
}
// IsPayoutToSbpDestinationData reports whether PayoutRequestPayoutDestinationData is PayoutToSbpDestinationData.
func (s PayoutRequestPayoutDestinationData) IsPayoutToSbpDestinationData() bool {
return s.Type == PayoutToSbpDestinationDataPayoutRequestPayoutDestinationData
// IsSbp reports whether PayoutRequestPayoutDestinationData is Sbp.
func (s PayoutRequestPayoutDestinationData) IsSbp() bool {
return s.Type == SbpPayoutRequestPayoutDestinationData
}
// SetPayoutToYooMoneyDestinationData sets PayoutRequestPayoutDestinationData to PayoutToYooMoneyDestinationData.
func (s *PayoutRequestPayoutDestinationData) SetPayoutToYooMoneyDestinationData(v PayoutToYooMoneyDestinationData) {
s.Type = PayoutToYooMoneyDestinationDataPayoutRequestPayoutDestinationData
s.PayoutToYooMoneyDestinationData = v
// SetYooMoney sets PayoutRequestPayoutDestinationData to YooMoney.
func (s *PayoutRequestPayoutDestinationData) SetYooMoney(v YooMoney) {
s.Type = YooMoneyPayoutRequestPayoutDestinationData
s.YooMoney = v
}
// GetPayoutToYooMoneyDestinationData returns PayoutToYooMoneyDestinationData and true boolean if PayoutRequestPayoutDestinationData is PayoutToYooMoneyDestinationData.
func (s PayoutRequestPayoutDestinationData) GetPayoutToYooMoneyDestinationData() (v PayoutToYooMoneyDestinationData, ok bool) {
if !s.IsPayoutToYooMoneyDestinationData() {
// GetYooMoney returns YooMoney and true boolean if PayoutRequestPayoutDestinationData is YooMoney.
func (s PayoutRequestPayoutDestinationData) GetYooMoney() (v YooMoney, ok bool) {
if !s.IsYooMoney() {
return v, false
}
return s.PayoutToYooMoneyDestinationData, true
return s.YooMoney, true
}
// NewPayoutToYooMoneyDestinationDataPayoutRequestPayoutDestinationData returns new PayoutRequestPayoutDestinationData from PayoutToYooMoneyDestinationData.
func NewPayoutToYooMoneyDestinationDataPayoutRequestPayoutDestinationData(v PayoutToYooMoneyDestinationData) PayoutRequestPayoutDestinationData {
// NewYooMoneyPayoutRequestPayoutDestinationData returns new PayoutRequestPayoutDestinationData from YooMoney.
func NewYooMoneyPayoutRequestPayoutDestinationData(v YooMoney) PayoutRequestPayoutDestinationData {
var s PayoutRequestPayoutDestinationData
s.SetPayoutToYooMoneyDestinationData(v)
s.SetYooMoney(v)
return s
}
// SetPayoutToBankCardDestinationData sets PayoutRequestPayoutDestinationData to PayoutToBankCardDestinationData.
func (s *PayoutRequestPayoutDestinationData) SetPayoutToBankCardDestinationData(v PayoutToBankCardDestinationData) {
s.Type = PayoutToBankCardDestinationDataPayoutRequestPayoutDestinationData
s.PayoutToBankCardDestinationData = v
// SetBankCard sets PayoutRequestPayoutDestinationData to BankCard.
func (s *PayoutRequestPayoutDestinationData) SetBankCard(v BankCard) {
s.Type = BankCardPayoutRequestPayoutDestinationData
s.BankCard = v
}
// GetPayoutToBankCardDestinationData returns PayoutToBankCardDestinationData and true boolean if PayoutRequestPayoutDestinationData is PayoutToBankCardDestinationData.
func (s PayoutRequestPayoutDestinationData) GetPayoutToBankCardDestinationData() (v PayoutToBankCardDestinationData, ok bool) {
if !s.IsPayoutToBankCardDestinationData() {
// GetBankCard returns BankCard and true boolean if PayoutRequestPayoutDestinationData is BankCard.
func (s PayoutRequestPayoutDestinationData) GetBankCard() (v BankCard, ok bool) {
if !s.IsBankCard() {
return v, false
}
return s.PayoutToBankCardDestinationData, true
return s.BankCard, true
}
// NewPayoutToBankCardDestinationDataPayoutRequestPayoutDestinationData returns new PayoutRequestPayoutDestinationData from PayoutToBankCardDestinationData.
func NewPayoutToBankCardDestinationDataPayoutRequestPayoutDestinationData(v PayoutToBankCardDestinationData) PayoutRequestPayoutDestinationData {
// NewBankCardPayoutRequestPayoutDestinationData returns new PayoutRequestPayoutDestinationData from BankCard.
func NewBankCardPayoutRequestPayoutDestinationData(v BankCard) PayoutRequestPayoutDestinationData {
var s PayoutRequestPayoutDestinationData
s.SetPayoutToBankCardDestinationData(v)
s.SetBankCard(v)
return s
}
// SetPayoutToSbpDestinationData sets PayoutRequestPayoutDestinationData to PayoutToSbpDestinationData.
func (s *PayoutRequestPayoutDestinationData) SetPayoutToSbpDestinationData(v PayoutToSbpDestinationData) {
s.Type = PayoutToSbpDestinationDataPayoutRequestPayoutDestinationData
s.PayoutToSbpDestinationData = v
// SetSbp sets PayoutRequestPayoutDestinationData to Sbp.
func (s *PayoutRequestPayoutDestinationData) SetSbp(v Sbp) {
s.Type = SbpPayoutRequestPayoutDestinationData
s.Sbp = v
}
// GetPayoutToSbpDestinationData returns PayoutToSbpDestinationData and true boolean if PayoutRequestPayoutDestinationData is PayoutToSbpDestinationData.
func (s PayoutRequestPayoutDestinationData) GetPayoutToSbpDestinationData() (v PayoutToSbpDestinationData, ok bool) {
if !s.IsPayoutToSbpDestinationData() {
// GetSbp returns Sbp and true boolean if PayoutRequestPayoutDestinationData is Sbp.
func (s PayoutRequestPayoutDestinationData) GetSbp() (v Sbp, ok bool) {
if !s.IsSbp() {
return v, false
}
return s.PayoutToSbpDestinationData, true
return s.Sbp, true
}
// NewPayoutToSbpDestinationDataPayoutRequestPayoutDestinationData returns new PayoutRequestPayoutDestinationData from PayoutToSbpDestinationData.
func NewPayoutToSbpDestinationDataPayoutRequestPayoutDestinationData(v PayoutToSbpDestinationData) PayoutRequestPayoutDestinationData {
// NewSbpPayoutRequestPayoutDestinationData returns new PayoutRequestPayoutDestinationData from Sbp.
func NewSbpPayoutRequestPayoutDestinationData(v Sbp) PayoutRequestPayoutDestinationData {
var s PayoutRequestPayoutDestinationData
s.SetPayoutToSbpDestinationData(v)
s.SetSbp(v)
return s
}
@@ -18935,33 +18973,6 @@ func (s *PayoutStatus) UnmarshalText(data []byte) error {
}
}
// Merged schema.
// Ref: #/components/schemas/PayoutToBankCardDestinationData
type PayoutToBankCardDestinationData struct {
Type PayoutDestinationDataType `json:"type"`
Card CardDataForPayoutDestination `json:"card"`
}
// GetType returns the value of Type.
func (s *PayoutToBankCardDestinationData) GetType() PayoutDestinationDataType {
return s.Type
}
// GetCard returns the value of Card.
func (s *PayoutToBankCardDestinationData) GetCard() CardDataForPayoutDestination {
return s.Card
}
// SetType sets the value of Type.
func (s *PayoutToBankCardDestinationData) SetType(val PayoutDestinationDataType) {
s.Type = val
}
// SetCard sets the value of Card.
func (s *PayoutToBankCardDestinationData) SetCard(val CardDataForPayoutDestination) {
s.Card = val
}
// Merged schema.
// Ref: #/components/schemas/PayoutToCardDestination
type PayoutToCardDestination struct {
@@ -19044,44 +19055,6 @@ func (s *PayoutToSbpDestination) SetRecipientChecked(val bool) {
s.RecipientChecked = val
}
// Merged schema.
// Ref: #/components/schemas/PayoutToSbpDestinationData
type PayoutToSbpDestinationData struct {
Type PayoutDestinationDataType `json:"type"`
Phone string `json:"phone"`
BankID string `json:"bank_id"`
}
// GetType returns the value of Type.
func (s *PayoutToSbpDestinationData) GetType() PayoutDestinationDataType {
return s.Type
}
// GetPhone returns the value of Phone.
func (s *PayoutToSbpDestinationData) GetPhone() string {
return s.Phone
}
// GetBankID returns the value of BankID.
func (s *PayoutToSbpDestinationData) GetBankID() string {
return s.BankID
}
// SetType sets the value of Type.
func (s *PayoutToSbpDestinationData) SetType(val PayoutDestinationDataType) {
s.Type = val
}
// SetPhone sets the value of Phone.
func (s *PayoutToSbpDestinationData) SetPhone(val string) {
s.Phone = val
}
// SetBankID sets the value of BankID.
func (s *PayoutToSbpDestinationData) SetBankID(val string) {
s.BankID = val
}
// Merged schema.
// Ref: #/components/schemas/PayoutToYooMoneyDestination
type PayoutToYooMoneyDestination struct {
@@ -19109,33 +19082,6 @@ func (s *PayoutToYooMoneyDestination) SetAccountNumber(val YooMoneyAccountNumber
s.AccountNumber = val
}
// Merged schema.
// Ref: #/components/schemas/PayoutToYooMoneyDestinationData
type PayoutToYooMoneyDestinationData struct {
Type PayoutDestinationDataType `json:"type"`
AccountNumber string `json:"account_number"`
}
// GetType returns the value of Type.
func (s *PayoutToYooMoneyDestinationData) GetType() PayoutDestinationDataType {
return s.Type
}
// GetAccountNumber returns the value of AccountNumber.
func (s *PayoutToYooMoneyDestinationData) GetAccountNumber() string {
return s.AccountNumber
}
// SetType sets the value of Type.
func (s *PayoutToYooMoneyDestinationData) SetType(val PayoutDestinationDataType) {
s.Type = val
}
// SetAccountNumber sets the value of AccountNumber.
func (s *PayoutToYooMoneyDestinationData) SetAccountNumber(val string) {
s.AccountNumber = val
}
type PayoutsGetInternalServerError TooManyRequests
func (*PayoutsGetInternalServerError) payoutsGetRes() {}
@@ -23333,6 +23279,44 @@ func (s *SavePaymentMethodType) UnmarshalText(data []byte) error {
}
}
// Merged schema.
// Ref: #/components/schemas/sbp
type Sbp struct {
Type PayoutDestinationDataType `json:"type"`
Phone string `json:"phone"`
BankID string `json:"bank_id"`
}
// GetType returns the value of Type.
func (s *Sbp) GetType() PayoutDestinationDataType {
return s.Type
}
// GetPhone returns the value of Phone.
func (s *Sbp) GetPhone() string {
return s.Phone
}
// GetBankID returns the value of BankID.
func (s *Sbp) GetBankID() string {
return s.BankID
}
// SetType sets the value of Type.
func (s *Sbp) SetType(val PayoutDestinationDataType) {
s.Type = val
}
// SetPhone sets the value of Phone.
func (s *Sbp) SetPhone(val string) {
s.Phone = val
}
// SetBankID sets the value of BankID.
func (s *Sbp) SetBankID(val string) {
s.BankID = val
}
type SbpBankBic string
type SbpBankId string
@@ -24787,4 +24771,31 @@ type WebhooksWebhookIDDeleteOK struct{}
func (*WebhooksWebhookIDDeleteOK) webhooksWebhookIDDeleteRes() {}
// Merged schema.
// Ref: #/components/schemas/yoo_money
type YooMoney struct {
Type PayoutDestinationDataType `json:"type"`
AccountNumber string `json:"account_number"`
}
// GetType returns the value of Type.
func (s *YooMoney) GetType() PayoutDestinationDataType {
return s.Type
}
// GetAccountNumber returns the value of AccountNumber.
func (s *YooMoney) GetAccountNumber() string {
return s.AccountNumber
}
// SetType sets the value of Type.
func (s *YooMoney) SetType(val PayoutDestinationDataType) {
s.Type = val
}
// SetAccountNumber sets the value of AccountNumber.
func (s *YooMoney) SetAccountNumber(val string) {
s.AccountNumber = val
}
type YooMoneyAccountNumber string

View File

@@ -625,6 +625,40 @@ func (s BadRequestType) Validate() error {
}
}
func (s *BankCard) Validate() error {
if s == nil {
return validate.ErrNilPointer
}
var failures []validate.FieldError
if err := func() error {
if err := s.Type.Validate(); err != nil {
return err
}
return nil
}(); err != nil {
failures = append(failures, validate.FieldError{
Name: "type",
Error: err,
})
}
if err := func() error {
if err := s.Card.Validate(); err != nil {
return err
}
return nil
}(); err != nil {
failures = append(failures, validate.FieldError{
Name: "card",
Error: err,
})
}
if len(failures) > 0 {
return &validate.Error{Fields: failures}
}
return nil
}
func (s *BankCardData) Validate() error {
if s == nil {
return validate.ErrNilPointer
@@ -8892,18 +8926,18 @@ func (s *PayoutRequestAmount) Validate() error {
func (s PayoutRequestPayoutDestinationData) Validate() error {
switch s.Type {
case PayoutToYooMoneyDestinationDataPayoutRequestPayoutDestinationData:
if err := s.PayoutToYooMoneyDestinationData.Validate(); err != nil {
case YooMoneyPayoutRequestPayoutDestinationData:
if err := s.YooMoney.Validate(); err != nil {
return err
}
return nil
case PayoutToBankCardDestinationDataPayoutRequestPayoutDestinationData:
if err := s.PayoutToBankCardDestinationData.Validate(); err != nil {
case BankCardPayoutRequestPayoutDestinationData:
if err := s.BankCard.Validate(); err != nil {
return err
}
return nil
case PayoutToSbpDestinationDataPayoutRequestPayoutDestinationData:
if err := s.PayoutToSbpDestinationData.Validate(); err != nil {
case SbpPayoutRequestPayoutDestinationData:
if err := s.Sbp.Validate(); err != nil {
return err
}
return nil
@@ -9029,40 +9063,6 @@ func (s PayoutStatus) Validate() error {
}
}
func (s *PayoutToBankCardDestinationData) Validate() error {
if s == nil {
return validate.ErrNilPointer
}
var failures []validate.FieldError
if err := func() error {
if err := s.Type.Validate(); err != nil {
return err
}
return nil
}(); err != nil {
failures = append(failures, validate.FieldError{
Name: "type",
Error: err,
})
}
if err := func() error {
if err := s.Card.Validate(); err != nil {
return err
}
return nil
}(); err != nil {
failures = append(failures, validate.FieldError{
Name: "card",
Error: err,
})
}
if len(failures) > 0 {
return &validate.Error{Fields: failures}
}
return nil
}
func (s *PayoutToCardDestination) Validate() error {
if s == nil {
return validate.ErrNilPointer
@@ -9173,75 +9173,6 @@ func (s *PayoutToSbpDestination) Validate() error {
return nil
}
func (s *PayoutToSbpDestinationData) Validate() error {
if s == nil {
return validate.ErrNilPointer
}
var failures []validate.FieldError
if err := func() error {
if err := s.Type.Validate(); err != nil {
return err
}
return nil
}(); err != nil {
failures = append(failures, validate.FieldError{
Name: "type",
Error: err,
})
}
if err := func() error {
if err := (validate.String{
MinLength: 0,
MinLengthSet: false,
MaxLength: 0,
MaxLengthSet: false,
Email: false,
Hostname: false,
Regex: regexMap["[0-9]{4,15}"],
MinNumeric: 0,
MinNumericSet: false,
MaxNumeric: 0,
MaxNumericSet: false,
}).Validate(string(s.Phone)); err != nil {
return errors.Wrap(err, "string")
}
return nil
}(); err != nil {
failures = append(failures, validate.FieldError{
Name: "phone",
Error: err,
})
}
if err := func() error {
if err := (validate.String{
MinLength: 0,
MinLengthSet: false,
MaxLength: 12,
MaxLengthSet: true,
Email: false,
Hostname: false,
Regex: regexMap["[a-zA-Z0-9]{12}"],
MinNumeric: 0,
MinNumericSet: false,
MaxNumeric: 0,
MaxNumericSet: false,
}).Validate(string(s.BankID)); err != nil {
return errors.Wrap(err, "string")
}
return nil
}(); err != nil {
failures = append(failures, validate.FieldError{
Name: "bank_id",
Error: err,
})
}
if len(failures) > 0 {
return &validate.Error{Fields: failures}
}
return nil
}
func (s *PayoutToYooMoneyDestination) Validate() error {
if s == nil {
return validate.ErrNilPointer
@@ -9276,52 +9207,6 @@ func (s *PayoutToYooMoneyDestination) Validate() error {
return nil
}
func (s *PayoutToYooMoneyDestinationData) Validate() error {
if s == nil {
return validate.ErrNilPointer
}
var failures []validate.FieldError
if err := func() error {
if err := s.Type.Validate(); err != nil {
return err
}
return nil
}(); err != nil {
failures = append(failures, validate.FieldError{
Name: "type",
Error: err,
})
}
if err := func() error {
if err := (validate.String{
MinLength: 11,
MinLengthSet: true,
MaxLength: 33,
MaxLengthSet: true,
Email: false,
Hostname: false,
Regex: nil,
MinNumeric: 0,
MinNumericSet: false,
MaxNumeric: 0,
MaxNumericSet: false,
}).Validate(string(s.AccountNumber)); err != nil {
return errors.Wrap(err, "string")
}
return nil
}(); err != nil {
failures = append(failures, validate.FieldError{
Name: "account_number",
Error: err,
})
}
if len(failures) > 0 {
return &validate.Error{Fields: failures}
}
return nil
}
func (s *PayoutsGetInternalServerError) Validate() error {
alias := (*TooManyRequests)(s)
if err := alias.Validate(); err != nil {
@@ -12616,6 +12501,75 @@ func (s SavePaymentMethodType) Validate() error {
}
}
func (s *Sbp) Validate() error {
if s == nil {
return validate.ErrNilPointer
}
var failures []validate.FieldError
if err := func() error {
if err := s.Type.Validate(); err != nil {
return err
}
return nil
}(); err != nil {
failures = append(failures, validate.FieldError{
Name: "type",
Error: err,
})
}
if err := func() error {
if err := (validate.String{
MinLength: 0,
MinLengthSet: false,
MaxLength: 0,
MaxLengthSet: false,
Email: false,
Hostname: false,
Regex: regexMap["[0-9]{4,15}"],
MinNumeric: 0,
MinNumericSet: false,
MaxNumeric: 0,
MaxNumericSet: false,
}).Validate(string(s.Phone)); err != nil {
return errors.Wrap(err, "string")
}
return nil
}(); err != nil {
failures = append(failures, validate.FieldError{
Name: "phone",
Error: err,
})
}
if err := func() error {
if err := (validate.String{
MinLength: 0,
MinLengthSet: false,
MaxLength: 12,
MaxLengthSet: true,
Email: false,
Hostname: false,
Regex: regexMap["[a-zA-Z0-9]{12}"],
MinNumeric: 0,
MinNumericSet: false,
MaxNumeric: 0,
MaxNumericSet: false,
}).Validate(string(s.BankID)); err != nil {
return errors.Wrap(err, "string")
}
return nil
}(); err != nil {
failures = append(failures, validate.FieldError{
Name: "bank_id",
Error: err,
})
}
if len(failures) > 0 {
return &validate.Error{Fields: failures}
}
return nil
}
func (s SbpBankBic) Validate() error {
alias := (string)(s)
if err := (validate.String{
@@ -13831,6 +13785,52 @@ func (s WebhooksPostReqEvent) Validate() error {
}
}
func (s *YooMoney) Validate() error {
if s == nil {
return validate.ErrNilPointer
}
var failures []validate.FieldError
if err := func() error {
if err := s.Type.Validate(); err != nil {
return err
}
return nil
}(); err != nil {
failures = append(failures, validate.FieldError{
Name: "type",
Error: err,
})
}
if err := func() error {
if err := (validate.String{
MinLength: 11,
MinLengthSet: true,
MaxLength: 33,
MaxLengthSet: true,
Email: false,
Hostname: false,
Regex: nil,
MinNumeric: 0,
MinNumericSet: false,
MaxNumeric: 0,
MaxNumericSet: false,
}).Validate(string(s.AccountNumber)); err != nil {
return errors.Wrap(err, "string")
}
return nil
}(); err != nil {
failures = append(failures, validate.FieldError{
Name: "account_number",
Error: err,
})
}
if len(failures) > 0 {
return &validate.Error{Fields: failures}
}
return nil
}
func (s YooMoneyAccountNumber) Validate() error {
alias := (string)(s)
if err := (validate.String{

View File

@@ -27,7 +27,7 @@ func WithContext(ctx context.Context) Optional {
}
type Service interface {
CreatePayout(models.PayoutReq, *orm.User, ...Optional) error
CreatePayout(models.PayoutReq, *orm.User, string, ...Optional) (models.PayoutResp, error)
GetConfig() yookassaConf.YooKassa
}

View File

@@ -1,2 +1,11 @@
generator:
ignore_not_implemented: ["all"]
# features:
# enable:
# # Enables paths client generation
# - "paths/client"
# # Enables validation of client requests
# - "client/request/validation"
# # Enables validation of server responses
# - "server/response/validation"
# disable_all: true

View File

@@ -5040,7 +5040,6 @@ components:
discriminator:
propertyName: "type"
mapping:
bank_card: "#/components/schemas/PayoutToCardDestination"
yoo_money: "#/components/schemas/PayoutToYooMoneyDestination"
sbp: "#/components/schemas/PayoutToSbpDestination"
properties:

View File

@@ -2,6 +2,9 @@ package yookassa
import (
"context"
"errors"
"fmt"
"log/slog"
"net/http"
"payouts/internal/models"
"payouts/internal/service/database/orm"
@@ -31,8 +34,6 @@ func NewYookassaService(conf config.YooKassa) (Service, error) {
return nil, err
}
svc.payClient = payClient
// payClient.PaymentsPost()
return svc, nil
}
@@ -50,7 +51,7 @@ func (y *yookassaService) getParams(options ...Optional) *params {
func (y *yookassaService) BasicAuth(ctx context.Context, operationName gen.OperationName) (gen.BasicAuth, error) {
return gen.BasicAuth{
Username: y.conf.ApiPaymentKey,
Password: y.conf.ApiBaseSecret,
Password: y.conf.ApiPaymentSecret,
}, nil
}
@@ -60,12 +61,51 @@ func (y *yookassaService) OAuth2(ctx context.Context, operationName gen.Operatio
}
// CreatePayout implements [Service].
func (y *yookassaService) CreatePayout(req models.PayoutReq, userSession *orm.User, opts ...Optional) error {
func (y *yookassaService) CreatePayout(req models.PayoutReq, userSession *orm.User, idempotenceKey string, opts ...Optional) (models.PayoutResp, error) {
params := y.getParams(opts...)
y.payClient.PayoutsPost(params.ctx, &gen.PayoutRequest{}, gen.PayoutsPostParams{})
var payoutDestination gen.PayoutRequestPayoutDestinationData
return nil
switch req.PayoutType {
case models.TypeSBP:
payoutDestination = gen.NewSbpPayoutRequestPayoutDestinationData(gen.Sbp{
Type: gen.PayoutDestinationDataTypeSbp,
Phone: userSession.Phone,
})
case models.TypeYooMoney:
payoutDestination = gen.NewYooMoneyPayoutRequestPayoutDestinationData(gen.YooMoney{
Type: gen.PayoutDestinationDataTypeYooMoney,
AccountNumber: req.AccountNumber,
})
default:
return models.PayoutResp{Result: "failed", ErrorReason: "unsupported payout type"}, errors.New("unsupported payout type")
}
payoutOpt := gen.NewOptPayoutRequestPayoutDestinationData(payoutDestination)
postResp, err := y.payClient.PayoutsPost(params.ctx, &gen.PayoutRequest{
Amount: gen.PayoutRequestAmount{
Value: fmt.Sprintf("%.2f", req.Amount),
Currency: gen.CurrencyCodeRUB,
},
PayoutDestinationData: payoutOpt,
Test: gen.NewOptTest(gen.Test(y.conf.Test)),
}, gen.PayoutsPostParams{
IdempotenceKey: idempotenceKey,
})
slog.Debug(fmt.Sprintf("Received from yookassa: error %v; response %v", err, postResp))
if err == nil {
switch payoutResp := postResp.(type) {
case *gen.Payout:
slog.Info(fmt.Sprintf("Succeeded payout. It's id = %s", payoutResp.ID))
return models.PayoutResp{Result: string(payoutResp.Status), PayoutID: string(payoutResp.ID)}, nil
default:
return models.PayoutResp{Result: "failed", ErrorReason: fmt.Sprintf("%T", postResp)}, nil
}
}
return models.PayoutResp{Result: "failed", ErrorReason: errors.Join(errors.New("failed to call yookassa api"), err).Error()}, err
}
// GetConfig implements [Service].