package bitrix import ( "bytes" "encoding/json" "fmt" "github.com/google/uuid" "github.com/mitchellh/mapstructure" "github.com/sirupsen/logrus" "net/http" "os" "strings" "time" ) var EP = os.Getenv("BITRIX_API_EP") type ClientsResource struct { EntityId string `json:"entityId"` } type OrderResource struct { ID string `json:"id,omitempty"` Clients []ClientsResource `json:"clients"` Lid string `json:"lid,omitempty"` DateInsert time.Time `json:"dateInsert,omitempty"` DateUpdate time.Time `json:"dateUpdate,omitempty"` PersonTypeID string `json:"personTypeId,omitempty"` StatusID string `json:"statusId,omitempty"` DateStatus time.Time `json:"dateStatus,omitempty"` EmpStatusID any `json:"empStatusId,omitempty"` Marked string `json:"marked,omitempty"` DateMarked any `json:"dateMarked,omitempty"` EmpMarkedID any `json:"empMarkedId,omitempty"` ReasonMarked any `json:"reasonMarked,omitempty"` Price float64 `json:"price,omitempty"` DiscountValue string `json:"discountValue,omitempty"` TaxValue string `json:"taxValue,omitempty"` UserDescription string `json:"userDescription,omitempty"` AdditionalInfo any `json:"additionalInfo,omitempty"` Comments string `json:"comments,omitempty"` CompanyID string `json:"companyId,omitempty"` ResponsibleID any `json:"responsibleId,omitempty"` StatGid any `json:"statGid,omitempty"` DatePayBefore any `json:"datePayBefore,omitempty"` DateBill any `json:"dateBill,omitempty"` RecurringID any `json:"recurringId,omitempty"` LockedBy string `json:"lockedBy,omitempty"` DateLock time.Time `json:"dateLock,omitempty"` RecountFlag string `json:"recountFlag,omitempty"` AffiliateID any `json:"affiliateId,omitempty"` DeliveryDocNum any `json:"deliveryDocNum,omitempty"` DeliveryDocDate any `json:"deliveryDocDate,omitempty"` Updated1C string `json:"updated1c,omitempty"` OrderTopic any `json:"orderTopic,omitempty"` XMLID any `json:"xmlId,omitempty"` ID1C any `json:"id1c,omitempty"` Version1C any `json:"version1c,omitempty"` Version string `json:"version,omitempty"` ExternalOrder string `json:"externalOrder,omitempty"` StoreID any `json:"storeId,omitempty"` Canceled string `json:"canceled,omitempty"` EmpCanceledID any `json:"empCanceledId,omitempty"` DateCanceled any `json:"dateCanceled,omitempty"` ReasonCanceled any `json:"reasonCanceled,omitempty"` BasketItems []BasketResource `json:"basketItems,omitempty"` Properties []propertyValueResource `json:"properties,omitempty"` Payments []PaymentResource `json:"payments,omitempty"` Shipments []any `json:"shipments,omitempty"` } type propertyValueResource struct { Id string `json:"id"` Name string `json:"name"` Value []string `json:"value"` Code string `json:"code"` OrderPropsId string `json:"orderPropsId"` } type PaymentResource struct { Id string `json:"id"` OrderId string `json:"orderId"` Paid string `json:"paid"` DatePaid interface{} `json:"datePaid"` EmpPaidId interface{} `json:"empPaidId"` PaySystemId string `json:"paySystemId"` PsStatus interface{} `json:"psStatus"` PsStatusCode interface{} `json:"psStatusCode"` PsInvoiceId interface{} `json:"psInvoiceId"` PsStatusDescription interface{} `json:"psStatusDescription"` PsStatusMessage interface{} `json:"psStatusMessage"` PsSum interface{} `json:"psSum"` PsCurrency interface{} `json:"psCurrency"` PsResponseDate interface{} `json:"psResponseDate"` PayVoucherNum string `json:"payVoucherNum"` PayVoucherDate interface{} `json:"payVoucherDate"` DatePayBefore interface{} `json:"datePayBefore"` DateBill time.Time `json:"dateBill"` XmlId interface{} `json:"xmlId"` Sum string `json:"sum"` PriceCod string `json:"priceCod"` Currency string `json:"currency"` PaySystemName string `json:"paySystemName"` ResponsibleId interface{} `json:"responsibleId"` EmpResponsibleId interface{} `json:"empResponsibleId"` DateResponsibleId interface{} `json:"dateResponsibleId"` Comments interface{} `json:"comments"` CompanyId string `json:"companyId"` PayReturnNum string `json:"payReturnNum"` PayReturnDate interface{} `json:"payReturnDate"` EmpReturnId interface{} `json:"empReturnId"` PayReturnComment string `json:"payReturnComment"` IsReturn string `json:"isReturn"` Marked string `json:"marked"` DateMarked interface{} `json:"dateMarked"` EmpMarkedId interface{} `json:"empMarkedId"` ReasonMarked interface{} `json:"reasonMarked"` Updated1C string `json:"updated1c"` Id1C interface{} `json:"id1c"` Version1C interface{} `json:"version1c"` ExternalPayment string `json:"externalPayment"` } type BasketResource struct { Module string `json:"module"` ProductId string `json:"productId"` Id string `json:"id"` Lid string `json:"lid"` Quantity string `json:"quantity"` Weight string `json:"weight"` Price float64 `json:"price"` CustomPrice string `json:"customPrice"` BasePrice string `json:"basePrice"` ProductPriceId string `json:"productPriceId"` PriceTypeId string `json:"priceTypeId"` Currency string `json:"currency"` BarcodeMulti string `json:"barcodeMulti"` Name string `json:"name"` CatalogXmlId string `json:"catalogXmlId"` VatRate string `json:"vatRate"` Notes string `json:"notes"` DiscountPrice string `json:"discountPrice"` ProductProviderClass string `json:"productProviderClass"` Dimensions string `json:"dimensions"` Type interface{} `json:"type"` SetParentId interface{} `json:"setParentId"` DetailPageUrl string `json:"detailPageUrl"` MeasureCode string `json:"measureCode"` MeasureName string `json:"measureName"` OrderId string `json:"orderId"` ProductXmlId string `json:"productXmlId"` Subscribe string `json:"subscribe"` Recommendation interface{} `json:"recommendation"` VatIncluded string `json:"vatIncluded"` Sort string `json:"sort"` DiscountName interface{} `json:"discountName"` DiscountValue interface{} `json:"discountValue"` DiscountCoupon interface{} `json:"discountCoupon"` Properties []struct { Id string `json:"id"` BasketId string `json:"basketId"` Name string `json:"name"` Value string `json:"value"` Code string `json:"code"` Sort string `json:"sort"` } `json:"properties"` } type bitrix struct{} type Bitrix interface { CreateAnonymousUser() (int, error) CreateOrder(userId int) (int, error) ApprovePayment(paymentId int, paySystemId int) error CancelOrder(orderId int) error GetOrderInfo(orderId int) (*OrderResource, error) CreatePayment(orderId int, sum float64) error AddProductToOrder(orderId int, productId int, price float64, quantity int) error UpdateContact(contactId int, email string, name string, phone string) error } type createAnonymousUserRequest struct { Email string `json:"EMAIL"` Name string `json:"NAME"` Password string `json:"PASSWORD"` ConfirmPassword string `json:"CONFIRM_PASSWORD"` UFDepartment []int `json:"UF_DEPARTMENT"` } type createAnonymousUserResponse struct { Result int `json:"result"` } func (_ bitrix) CreateAnonymousUser() (int, error) { uid, _ := uuid.NewUUID() req := createAnonymousUserRequest{ Email: fmt.Sprintf("anonymous%s@anonym.ru", uid.String()), Name: "Анонимный пользователь", Password: uid.String(), ConfirmPassword: uid.String(), UFDepartment: []int{0}, } query, _ := json.Marshal(req) resp, err := http.Post(EP+"/user.add", "application/json", bytes.NewBuffer(query)) result := createAnonymousUserResponse{} err = json.NewDecoder(resp.Body).Decode(&result) return result.Result, err } type createOrderRequestWrapper struct { Fields createOrderRequest `json:"fields"` } type createOrderRequest struct { Lid string `json:"lid"` PersonTypeId int `json:"personTypeId"` Currency string `json:"currency"` UserId int `json:"userId"` } type createOrderResponse struct { Result struct { Order struct { Id int `json:"id"` } `json:"order"` } `json:"result"` } func (_ bitrix) CreateOrder(userId int) (int, error) { req := createOrderRequestWrapper{createOrderRequest{ Lid: "s2", PersonTypeId: 5, Currency: "RUB", UserId: userId, }} query, _ := json.Marshal(req) resp, _ := http.Post(EP+"/sale.order.add", "application/json", bytes.NewBuffer(query)) result := createOrderResponse{} err := json.NewDecoder(resp.Body).Decode(&result) return result.Result.Order.Id, err } func (_ bitrix) ApprovePayment(paymentId int, paySystemId int) error { req := map[string]interface{}{ "id": paymentId, "fields": map[string]interface{}{"paid": "Y", "paySystemId": paySystemId}, } query, _ := json.Marshal(req) _, err := http.Post(EP+"/sale.payment.update", "application/json", bytes.NewBuffer(query)) return err } func (_ bitrix) CancelOrder(orderId int) error { req := map[string]interface{}{ "id": orderId, "fields": map[string]interface{}{"canceled": "Y"}, } query, _ := json.Marshal(req) _, err := http.Post(EP+"/sale.order.update", "application/json", bytes.NewBuffer(query)) return err } func (_ bitrix) GetOrderInfo(orderId int) (*OrderResource, error) { req := map[string]interface{}{ "id": orderId, } query, _ := json.Marshal(req) response, err := http.Post(EP+"/sale.order.get", "application/json", bytes.NewBuffer(query)) result := struct { Result struct { Order map[string]interface{} `json:"order"` } `json:"result"` }{} err = json.NewDecoder(response.Body).Decode(&result) if err != nil { logrus.Errorf("Error: %s", err.Error()) } resultParsed := OrderResource{} mapstructure.Decode(result.Result.Order, &resultParsed) return &resultParsed, err } func (_ bitrix) CreatePayment(orderId int, sum float64) error { req := map[string]interface{}{ "fields": map[string]interface{}{ "orderId": orderId, "sum": sum, "paid": "N", "paySystemId": 8, }, } query, _ := json.Marshal(req) _, err := http.Post(EP+"/sale.payment.add", "application/json", bytes.NewBuffer(query)) return err } func (_ bitrix) AddProductToOrder(orderId int, productId int, price float64, quantity int) error { req := map[string]interface{}{ "fields": map[string]interface{}{ "orderId": orderId, "productId": productId, "quantity": quantity, "currency": "RUB", "price": price, }, } query, _ := json.Marshal(req) _, err := http.Post(EP+"/sale.basketitem.addCatalogProduct", "application/json", bytes.NewBuffer(query)) return err } func (_ bitrix) UpdateContact(contactId int, email string, name string, phone string) error { req := map[string]interface{}{ "id": contactId, "fields": map[string]interface{}{ "EMAIL": append([]map[string]interface{}{}, map[string]interface{}{ "VALUE_TYPE": "other", "VALUE": email, "TYPE_ID": "EMAIL", }), "NAME": strings.Split(name, " ")[1], "LAST_NAME": strings.Split(name, " ")[0], "SECOND_NAME": strings.Split(name, " ")[2], "PHONE": append([]map[string]interface{}{}, map[string]interface{}{ "VALUE_TYPE": "other", "VALUE": phone, "TYPE_ID": "PHONE", }), }, } query, _ := json.Marshal(req) _, err := http.Post(EP+"/crm.contact.update", "application/json", bytes.NewBuffer(query)) return err } func Initialize() Bitrix { return &bitrix{} }