Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 51 additions & 25 deletions api/api.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package api

import (
"math/rand"
"net/http"
"os"
"time"

"github.com/Iknite-Space/sqlc-example-api/campay"
"github.com/Iknite-Space/sqlc-example-api/db/repo"
"github.com/gin-gonic/gin"
)
Expand All @@ -25,62 +29,84 @@ func (h *MessageHandler) WireHttpHandler() http.Handler {
c.AbortWithStatus(http.StatusInternalServerError)
}))

r.POST("/message", h.handleCreateMessage)
r.GET("/message/:id", h.handleGetMessage)
r.GET("/thread/:id/messages", h.handleGetThreadMessages)
r.POST("/customer", h.handleCreateCustomer)
r.POST("/order/", h.handleCreateOrders)
// r.GET("/thread/:id/messages", h.handleGetThreadMessages)
//r.POST("/orders", h.handleCreateCustomerOrders)

return r
}

func (h *MessageHandler) handleCreateMessage(c *gin.Context) {
var req repo.CreateMessageParams
func (h *MessageHandler) handleCreateCustomer(c *gin.Context) {
var req repo.CreateCustomerParams
err := c.ShouldBindBodyWithJSON(&req)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}

message, err := h.querier.CreateMessage(c, req)
customer, err := h.querier.CreateCustomer(c, req)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}

c.JSON(http.StatusOK, message)
c.JSON(http.StatusOK, customer)
}

func (h *MessageHandler) handleGetMessage(c *gin.Context) {
id := c.Param("id")
if id == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "id is required"})
func (h *MessageHandler) handleCreateOrders(c *gin.Context) {
var req repo.CreateOrderParams
err := c.ShouldBindBodyWithJSON(&req)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}

message, err := h.querier.GetMessageByID(c, id)
order, err := h.querier.CreateOrder(c, req)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}

c.JSON(http.StatusOK, message)
}
num := "673501707"
amount := "13"
des := "order"
ref := GenerateRandomLetters(10)

func (h *MessageHandler) handleGetThreadMessages(c *gin.Context) {
id := c.Param("id")
if id == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "id is required"})
return
apik := os.Getenv("API_KEY")

reqpay := campay.Payment(apik, num, amount, des, ref)

time.Sleep(20 * time.Second)

state := campay.Status(apik, reqpay.Reference)

reqs := repo.UpadateOrderByIdParams{
ID: order.ID,
OrderStatus: state.Status,
}

messages, err := h.querier.GetMessagesByThread(c, id)
updatedOrder, err := h.querier.UpadateOrderById(c, reqs)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}

c.JSON(http.StatusOK, gin.H{
"thread": id,
"topic": "example",
"messages": messages,
})
c.JSON(http.StatusOK, gin.H{"Order Created": updatedOrder, "campay request": reqpay, "campay response": state})
}

// Function to generate random letters
func GenerateRandomLetters(n int) string {
// Define the set of characters to choose from
letters := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

// Create a new random generator with a source based on the current time
r := rand.New(rand.NewSource(time.Now().UnixNano()))

// Create a slice to store the random letters
randomLetters := make([]byte, n)
for i := 0; i < n; i++ {
randomLetters[i] = letters[r.Intn(len(letters))]
}
return string(randomLetters)
}
Binary file added bin/api
Binary file not shown.
51 changes: 51 additions & 0 deletions campay/PaymentStatus.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package campay

import (
"encoding/json"
"fmt"
"log"
"net/http"
)

type PaymentStatus struct {
Reference string `json:"reference"`
Status string `json:"status"`
}

func Status(apikey string, reference string) PaymentStatus {
client := &http.Client{}
var url = fmt.Sprintf("https://demo.campay.net/api/transaction/%s/", reference)

req, err := http.NewRequest("GET", url, nil)
if err != nil {
fmt.Printf(" could not make a new request")
log.Fatal(err)
}
req.Header.Set("Authorization", fmt.Sprintf("Token %s", apikey))
req.Header.Add("Content-Type", "application/json")

resp, err := client.Do(req)
if err != nil {
fmt.Printf(" check get request method")
log.Fatal(err)
}

defer func() {
if err := resp.Body.Close(); err != nil {
log.Printf("failed to close response body: %v", err)
}
}()

var state PaymentStatus
if err := json.NewDecoder(resp.Body).Decode(&state); err != nil {
log.Printf("failed to decode response: %v", err)

}
return state
// defer resp.Body.Close()

// var state PaymentStatus
// json.NewDecoder(resp.Body).Decode(&state)
// return state

}
72 changes: 72 additions & 0 deletions campay/RequestPayment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package campay

import (
"bytes"
"encoding/json"
"fmt"
"log"
"net/http"
)

type PaymentRequest struct {
From string `json:"from"`
Amount string `json:"amount"`
Description string `json:"description"`
External_Reference string `json:"external_reference"`
}

type PaymentResponse struct {
Reference string `json:"reference"`
Ussd_Code string `json:"ussd_code"`
}

func Payment(apikey string, number string, amount string, description string, external_reference string) PaymentResponse {

number = "237" + number

client := &http.Client{}

iraq := PaymentRequest{
From: number,
Amount: amount,
Description: description,
External_Reference: external_reference,
}

postbody, _ := json.Marshal(iraq)

postbodyparam := bytes.NewBuffer(postbody)

req, err := http.NewRequest("POST", "https://demo.campay.net/api/collect/", postbodyparam)

if err != nil {
fmt.Printf(" could not make a new request")
log.Fatal(err)
}
req.Header.Set("Authorization", fmt.Sprintf("Token %s", apikey))
req.Header.Add("Content-Type", "application/json")

response, err := client.Do(req)
if err != nil {
fmt.Println("Invalid Request, check POST request credentials")
log.Fatal(err)
}

defer func() {
if err := response.Body.Close(); err != nil {
log.Printf("failed to close response body: %v", err)
}
}()

var makepay PaymentResponse
if err := json.NewDecoder(response.Body).Decode(&makepay); err != nil {
log.Printf("failed to decode response: %v", err)
}

return makepay
// defer response.Body.Close()

// var makepay PaymentResponse
// json.NewDecoder(response.Body).Decode(&makepay)
// return makepay
}
4 changes: 1 addition & 3 deletions db/migrations/000001_init_schema.down.sql
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
DROP TABLE users;
DROP TYPE user_status;
DROP TYPE identity_document;
DROP TABLE customer;
17 changes: 6 additions & 11 deletions db/migrations/000001_init_schema.up.sql
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@




CREATE TABLE "message" (
"id" VARCHAR(36) PRIMARY KEY DEFAULT gen_random_uuid()::varchar(36),
"thread" VARCHAR(36) NOT NULL,
"sender" VARCHAR(100) NOT NULL,
"content" TEXT NOT NULL,
"created_at" TIMESTAMP DEFAULT now()
CREATE TABLE "customer" (
"id" VARCHAR(36) PRIMARY KEY DEFAULT gen_random_uuid()::varchar(36),
"customer_name" VARCHAR(100) NOT NULL,
"phone_number" VARCHAR(20) NOT NULL UNIQUE,
"email" VARCHAR(100) NOT NULL UNIQUE,
"created_at" TIMESTAMP DEFAULT now()
);

1 change: 1 addition & 0 deletions db/migrations/000002_orders_table.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE order
13 changes: 13 additions & 0 deletions db/migrations/000002_orders_table.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CREATE TABLE "order" (
"id" VARCHAR(36) PRIMARY KEY DEFAULT gen_random_uuid()::varchar(36),
"customer_id" VARCHAR(36) NOT NULL,
"product_name" VARCHAR(30) NOT NULL,
"price" VARCHAR(10) NOT NULL,
"order_status" VARCHAR(20) NOT NULL,
"order_date" TIMESTAMP DEFAULT now() NOT NULL,
FOREIGN KEY ("customer_id")
REFERENCES "customer"("id")
ON DELETE CASCADE
)


39 changes: 30 additions & 9 deletions db/query/message.sql
Original file line number Diff line number Diff line change
@@ -1,13 +1,34 @@
-- name: CreateMessage :one
INSERT INTO message (thread, sender, content)
-- -- name: CreateMessage :one
-- INSERT INTO message (thread, sender, content)
-- VALUES ($1, $2, $3)
-- RETURNING *;

-- -- name: GetMessageByID :one
-- SELECT * FROM message
-- WHERE id = $1;

-- -- name: GetMessagesByThread :many
-- SELECT * FROM message
-- WHERE thread = $1
-- ORDER BY created_at DESC;

-- -- name: CustomerOrders :many
-- INSERT INTO orders (reference, phone_number, amount, transaction_status, transaction_description)
-- VALUES ($1, $2, $3, $4, $5)
-- RETURNING *;

-- name: CreateCustomer :one
INSERT INTO customer (customer_name, phone_number, email)
VALUES ($1, $2, $3)
RETURNING *;

-- name: GetMessageByID :one
SELECT * FROM message
WHERE id = $1;
-- name: CreateOrder :one
INSERT INTO "order" (customer_id, product_name, price, order_status)
VALUES ($1, $2, $3, $4)
RETURNING *;

-- name: GetMessagesByThread :many
SELECT * FROM message
WHERE thread = $1
ORDER BY created_at DESC;
-- name: UpadateOrderById :one
UPDATE "order"
SET order_status = $2
WHERE id =$1
RETURNING *;
Loading