create a charge with Stripe and Delphi - api

I am trying to create a charge in Stripe following API documentation but without success :
jsnObj := TJSONObject.Create;
jsnObj.AddPair('amount', TJSONNumber.Create('111'));
jsnObj.AddPair('currency', 'eur');
jsnObj.AddPair('customer', 'cus_JL30ptApR3U2gL');
jsnObj.AddPair('description', 'My First Test');
ss := TStringStream.Create(jsnObj.ToString);
rs := TStringStream.Create;
IdHTTP1.Request.BasicAuthentication := True;
IdHTTP1.Request.Username := ApiKey ; // test private key
IdHTTP1.Post('https://api.stripe.com/v1/charges', ss, rs);
StatusBar1.SimpleText := IdHTTP1.ResponseText;
the result is always error :
{
"error": {
"code": "parameter_missing",
"doc_url": "https://stripe.com/docs/error-codes/parameter-missing",
"message": "Must provide source or customer.",
"type": "invalid_request_error"
}
}
Http returns 400 bad request.
All data is correct but the source parameter is missing as Stripe documentation states that it is optional so I include customer parameter instead and it should work.
Other calls to the Stripe API are successful with the same code (connect, retrieve objects etc.)
Thanks for any tips..

Related

dsnap.Data() returns nil if the document does not exist

I have written a controller GetUser to get a particular user from Database(Firestore) on the basis of id I put in the query. If the user is not present in the database then it should give the message that "User not found". But along with this message I am getting nil keyword also in response.
The response I am getting:
{
"message": "User not found"
}null
When I hover on dsnap.Data() I get the information that
(firestore.DocumentSnapshot).Data on pkg.go.dev
Data returns the DocumentSnapshot's fields as a map. It is equivalent to
var m map[string]interface{}
d.DataTo(&m)
except that it returns nil if the document does not exist.
Controller:
func GetUser(c *gin.Context) {
paramID := c.Params.ByName("id")
........
........
........
dsnap, err := client.Collection("users").Doc(paramID).Get(ctx)
if err != nil {
fmt.Print(err)
c.IndentedJSON(http.StatusNotFound, gin.H{
"message": "User not found",
})
}
m := dsnap.Data()
c.IndentedJSON(http.StatusNotFound, gin.H(m))
}
Firestore reference link: https://pkg.go.dev/cloud.google.com/go/firestore#v1.6.1#DocumentSnapshot.Data
Can you guys please tell me how can I remove nil from the response?
Thank you.
This problem is solved now. I write "return" after the User not found response.

Getting "multipart: NextPart: EOF" error when reading multipart/form-data

I am building a router layer for an API where I take the response and extract a parameter (in this case a service_code, the name can vary - service_code, serviceCode, code need to handle all) from the request body and pass it to the service that needs it. The data can be in raw json format application/json , query params, path params or as form data multipart/form-data. I am able to do it with the others but with form, when I pass the payload to the destination service I get the error multipart: NextPart: EOF.
Here is how I am reading the data:
c.MultipartForm()
postForm := c.Request.PostForm
queryParams := c.Request.URL.Query()
route := c.Request.URL.Path
body, _ := ioutil.ReadAll(c.Request.Body)
serviceCode, destUrl, payload := getCityCode(queryParams, route, body, postForm)
Then I pass this payload to http.NewRequest
http.NewRequest(method, destUrl, strings.NewReader(payload))
At the destination when I read the data:
data := models.Data{}
err := c.Bind(&data); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
The error is multipart: NextPart: EOF. Can someone help please!
This error happens when the form is empty because you are reading all the stream data with ioutil before binding it. You should change your code to use the information you need after binding it.

FTX FIX protocol returns "Invalid signature" message

I have been trying to to implement a FIX Client in Go to interact with FTX. To send the initial logon message, FTX's API doc asks the client to include a signature in the message.
In the return message from the FTX, it says "Invalid signature".
Below is my implementation for generating the signature:
func signatureGenerator(msgType, msgSeqNum, senderCompID, targetCompID string) string {
timeNow := time.Now().UTC().Format("20060102-15:04:05")
message := [][]byte{[]byte(timeNow),
[]byte(msgType),
[]byte(msgSeqNum),
[]byte(senderCompID),
[]byte(targetCompID)}
SOH := []byte{0x01}
signature := bytes.Join(message, SOH)
signSha256 := hmac.New(sha256.New, []byte(userInfo.CLIENT_API_SECRET))
signSha256.Write(signature)
strSig := hex.EncodeToString(signSha256.Sum(nil))
return strSig
}

Golang api (with buffalo) retrieve Post datas

I am developing an API in Golang (with Buffalo library).
I have my route set to point to :
func (ur UserResource) Create(c buffalo.Context) error {
// new User
u := &models.User{}
if err := c.Bind(u); err != nil {
return c.Render(500, r.String(err.Error()))
}
id, _ := uuid.NewV4()
u.ID = id
db[u.ID] = *u
return c.Render(201, r.JSON(u))
}
The problem is that when I test my api I have the following error :
(and my header Content-Type is set to multipart/form-data)
If I change the way values are passed to form-url-encoded and set no header, I have this error :
invalid character 'i' in literal false (expecting 'a')

400 error getting oauth user token in golang?

I tried to get the ebay user token.
I've alreay gotten auth code in ebay, but can't get user token with auth code.
Code is following:
status := ctx.UserValue("status").(string)
applicationToken := string(ctx.QueryArgs().Peek("code"))
log.Println("ApplicationToken: ", applicationToken)
log.Println("Status: ", status)
if status == "declined" {
    fmt.Printf("User doesn't give permission. Go back to your dashboard.")
    ctx.Redirect("/dashboard", fasthttp.StatusSeeOther)
}
//var appConfig = config.Config()
client := &http.Client{}
applicationTokenURLEncoded, _ := url.Parse(applicationToken)
body := url.Values{
    "grant_type": {"authorization_code"},
    "code": {applicationTokenURLEncoded.String()},
    "redirect_uri": {Runame},
}
reqBody := bytes.NewBufferString(body.Encode())
log.Println("Reqbody: ", reqBody)
req, _ := http.NewRequest("POST", "https://api.sandbox.ebay.com/identity/v1/oauth2/token", reqBody)
authorization := “AppID” + ":" + “CertID”
authorizationBase64 := base64.StdEncoding.EncodeToString([]byte(authorization))
req.Header.Add("Authorization", "Basic "+authorizationBase64)
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
log.Println("Body: ", req)
resp, _ := client.Do(req)
log.Println("resp: ", resp)
log.Println("ResBody: ", resp.Body)
And the error is like that:
Bad Request 400
I looks like the message isn't formed correctly (which is why the server returns 400).
When you're setting your headers you write:
req.Header.Add("Authorization", "Basic "+authorizationBase64)
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
Golang has a nice built in way to add Authorization to a Header: SetBasicAuth, which is a method of http.Request.
func (r *Request) SetBasicAuth(username, password string)
SetBasicAuth sets the request's Authorization header to use HTTP Basic Authentication with the provided username and password.
With HTTP Basic Authentication the provided username and password are not encrypted.
So instead of setting the Authorization Header manually, you could try:
req.SetBasicAuth("AppID”, “CertID”)
You were using something called CertID, but I think you meant ClientId and ClientSecret -- respectively user and password
I don't know if this is the cause of your problem :). One way to help find out, is consistent error checking, see your line:
applicationTokenURLEncoded, _ := url.Parse(applicationToken)