0
votes

I have developed a Go app. A webhook has been integrated. I have been successful in getting the payload (JSON format) from the webhook. However, I can't seem to do a redirect.

Step 1: User make payment at page /live.

Step 2: Upon successful payment, my payment processing company send a POST request to my webhook (/paymentsucess). payment function is called. In payment(), I was able to decode the JSON data that was POST to /paymentsucess and fmt.Println accordingly.

http.HandleFunc("/paymentsuccess", payment)

Now in Step 3, I want to redirect the user (which is still seeing /live) to a page (/thankyou) on successful payment. In the JSON posted to the webhook, there is a payment status field. I was able to do a if condition to check that this field has value "success". In such case, fmt.Println("redirecting to thank you"). This is all good. Then in the next line (inside payment() function), I added the below

http.Redirect(w, r, "/thankyou", http.StatusSeeOther)

I was expecting the current client page (which is still at /live) to redirect to /thankyou. But this is not happening.

How should one handle webhook redirects?

UPDATE When the webhook post successfully to payment(), I receive the below response and request

response

&{0xc00029c1e0 0xc0002a0700 0xc000386300 0x1120e20 false false false false 0 {0 0} 0xc000386200 {0xc0003a67e0 map[] false false} map[] false 0 -1 0 false false [] 0 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0] 0xc0003481c0 0}

request

&{POST /paymentsuccess HTTP/1.1 1 1 map[Accept:[*/*] Accept-Encoding:[gzip] Content-Length:[3162] Content-Type:[application/json] User-Agent:[Omise/2019-05-29] X-Datadog-Parent-Id:[6096593905335487199] X-Datadog-Sampling-Priority:[1] X-Datadog-Trace-Id:[8016780258334486542] X-Forwarded-For:[52.74.199.175] X-Forwarded-Proto:[https]] 0xc000386300 <nil> 3162 [] false d4e7c3fca000.ngrok.io:443 map[] map[] <nil> map[] [::1]:60999 /paymentsuccess <nil> <nil> <nil> 0xc000386340}

UPDATE 2 Thanks to @gipsy I as able to implement the steps he suggested. Right up to Step 4. I have a goroutine who poll query mysql database every two seconds to check for payment status. Once so, I was able to fmt.Println accordingly. So that confirms that I can confirm payment. BUT... I have trouble redirecting the current client page (user is at /live)...

func startPolling1(ShopName, SourceID, Status string) (string, bool) {
    for {
        time.Sleep(2 * time.Second)
        Amount, Result := queryDBForPaymentSuccess(ShopName, SourceID, Status)
        if Result == true {
            fmt.Println("found result")
            fmt.Println("no more polling")

            //HOW DO I DO A REDIRECT HERE? http.Redirect won't work because of error "superfluous response.WriteHeader call"

            break
        }
    }
    return Amount, Result
}

func livemode(res http.ResponseWriter, req *http.Request) {
if !alreadyLoggedIn(req) {
        http.Redirect(res, req, "/", http.StatusSeeOther)
        return
    }
    Shop = getUser(res, req)

    if req.Method == http.MethodPost {
       //Some codes here
       go startPolling1(Shop.Shopname, Charge.Source.ID, "successful")
       //Some codes here
     }
   }
 tpl.ExecuteTemplate(res, "golive.html", data1)
}
1
What is happening? Can you show some actual debug output? I.e. if you do a query with curl -v, what output do you see?Flimzy
@Flimzy I'm not sure. I am a new programmer so is still very amateur. I have updated my post with the response and request. The POST request to /paymentsuccess is good. But I just can't redirect my user to /thankyou. I was thinking, if the right way is to set my webhook to be /live?Ewan Sou

1 Answers

0
votes

First of all the web-hook request coming to your server is totally independent from the request you get from your user. So a redirect you try in the web-hook handle is not going to work

I think there could be many way to handle this. One way could be:

  1. Let the user submit the payment at /live( which you are doing)
  2. As part of completing the payment set status for that payment request in your db , say pending.
  3. When the web-hook arrives update the status to completed.
  4. Keep polling for the payment status from /live and when it see completed redirect user to wherever you want.
  5. You could use an ajax call to your server for the status check.