trying to fix qr
All checks were successful
build-and-deploy / build-deploy (push) Successful in 35s
All checks were successful
build-and-deploy / build-deploy (push) Successful in 35s
This commit is contained in:
@@ -31,10 +31,30 @@ class PayuQrRequestSchemaFix(
|
||||
status varchar not null,
|
||||
request_payload text,
|
||||
response_payload text,
|
||||
expiry_at timestamptz,
|
||||
created_at timestamptz not null
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
} else {
|
||||
val hasExpiryAt = jdbcTemplate.queryForObject(
|
||||
"""
|
||||
select count(*)
|
||||
from information_schema.columns
|
||||
where table_name = 'payu_qr_request'
|
||||
and column_name = 'expiry_at'
|
||||
""".trimIndent(),
|
||||
Int::class.java
|
||||
) ?: 0
|
||||
if (hasExpiryAt == 0) {
|
||||
logger.info("Adding expiry_at to payu_qr_request table")
|
||||
jdbcTemplate.execute(
|
||||
"""
|
||||
alter table payu_qr_request
|
||||
add column expiry_at timestamptz
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.android.trisolarisserver.component.PropertyAccess
|
||||
import com.android.trisolarisserver.controller.dto.PaymentCreateRequest
|
||||
import com.android.trisolarisserver.controller.dto.PaymentResponse
|
||||
import com.android.trisolarisserver.db.repo.BookingRepo
|
||||
import com.android.trisolarisserver.models.booking.BookingStatus
|
||||
import com.android.trisolarisserver.models.booking.Payment
|
||||
import com.android.trisolarisserver.models.booking.PaymentMethod
|
||||
import com.android.trisolarisserver.models.property.Role
|
||||
@@ -105,6 +106,12 @@ class Payments(
|
||||
if (booking.property.id != propertyId) {
|
||||
throw ResponseStatusException(HttpStatus.NOT_FOUND, "Booking not found for property")
|
||||
}
|
||||
if (booking.status != BookingStatus.OPEN && booking.status != BookingStatus.CHECKED_IN) {
|
||||
throw ResponseStatusException(
|
||||
HttpStatus.BAD_REQUEST,
|
||||
"Cash payments can only be deleted for OPEN or CHECKED_IN bookings"
|
||||
)
|
||||
}
|
||||
val payment = paymentRepo.findById(paymentId).orElseThrow {
|
||||
ResponseStatusException(HttpStatus.NOT_FOUND, "Payment not found")
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ class PayuQrPayments(
|
||||
private val payuQrRequestRepo: PayuQrRequestRepo,
|
||||
private val restTemplate: RestTemplate
|
||||
) {
|
||||
private val defaultExpirySeconds = 30 * 60
|
||||
|
||||
@PostMapping("/qr")
|
||||
@Transactional
|
||||
@@ -79,6 +80,31 @@ class PayuQrPayments(
|
||||
throw ResponseStatusException(HttpStatus.CONFLICT, "Amount exceeds pending")
|
||||
}
|
||||
val amountLong = requestedAmount ?: pending
|
||||
val expirySeconds = request.expirySeconds
|
||||
?: request.expiryMinutes?.let { it * 60 }
|
||||
?: defaultExpirySeconds
|
||||
|
||||
val existing = payuQrRequestRepo.findTopByBookingIdAndAmountAndCurrencyAndStatusOrderByCreatedAtDesc(
|
||||
bookingId,
|
||||
amountLong,
|
||||
booking.property.currency,
|
||||
PayuQrStatus.SENT
|
||||
)
|
||||
if (existing != null) {
|
||||
val expiryAt = existing.expiryAt
|
||||
val responsePayload = existing.responsePayload
|
||||
if (expiryAt != null && !responsePayload.isNullOrBlank()) {
|
||||
val now = OffsetDateTime.now()
|
||||
if (now.isBefore(expiryAt)) {
|
||||
return PayuQrGenerateResponse(
|
||||
txnid = existing.txnid,
|
||||
amount = amountLong,
|
||||
currency = booking.property.currency,
|
||||
payuResponse = responsePayload
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val txnid = "QR${bookingId.toString().substring(0, 8)}${System.currentTimeMillis()}"
|
||||
val productInfo = "Booking $bookingId"
|
||||
@@ -132,9 +158,9 @@ class PayuQrPayments(
|
||||
add("hash", hash)
|
||||
add("udf1", udf1)
|
||||
add("udf2", udf2)
|
||||
if (udf3.isNotBlank()) add("udf3", udf3)
|
||||
if (udf4.isNotBlank()) add("udf4", udf4)
|
||||
if (udf5.isNotBlank()) add("udf5", udf5)
|
||||
add("udf3", udf3) // always
|
||||
add("udf4", udf4) // always
|
||||
add("udf5", udf5) // always
|
||||
add("txn_s2s_flow", "4")
|
||||
val clientIp = request.clientIp?.trim()?.ifBlank { null }
|
||||
?: extractClientIp(httpRequest)
|
||||
@@ -143,9 +169,7 @@ class PayuQrPayments(
|
||||
?: throw ResponseStatusException(HttpStatus.BAD_REQUEST, "deviceInfo required")
|
||||
add("s2s_client_ip", clientIp)
|
||||
add("s2s_device_info", deviceInfo)
|
||||
val expirySeconds = request.expirySeconds
|
||||
?: request.expiryMinutes?.let { it * 60 }
|
||||
expirySeconds?.let { add("expiry_time", it.toString()) }
|
||||
add("expiry_time", expirySeconds.toString())
|
||||
request.address1?.trim()?.ifBlank { null }?.let { add("address1", it) }
|
||||
request.address2?.trim()?.ifBlank { null }?.let { add("address2", it) }
|
||||
request.city?.trim()?.ifBlank { null }?.let { add("city", it) }
|
||||
@@ -158,6 +182,8 @@ class PayuQrPayments(
|
||||
entry.value.joinToString("&") { value -> "${entry.key}=$value" }
|
||||
}
|
||||
|
||||
val createdAt = OffsetDateTime.now()
|
||||
val expiryAt = createdAt.plusSeconds(expirySeconds.toLong())
|
||||
val record = payuQrRequestRepo.save(
|
||||
PayuQrRequest(
|
||||
property = booking.property,
|
||||
@@ -167,7 +193,8 @@ class PayuQrPayments(
|
||||
currency = booking.property.currency,
|
||||
status = PayuQrStatus.CREATED,
|
||||
requestPayload = requestPayload,
|
||||
createdAt = OffsetDateTime.now()
|
||||
expiryAt = expiryAt,
|
||||
createdAt = createdAt
|
||||
)
|
||||
)
|
||||
|
||||
@@ -214,7 +241,7 @@ class PayuQrPayments(
|
||||
}
|
||||
|
||||
private fun sha512(input: String): String {
|
||||
val bytes = MessageDigest.getInstance("SHA-512").digest(input.toByteArray())
|
||||
val bytes = MessageDigest.getInstance("SHA-512").digest(input.toByteArray(Charsets.UTF_8))
|
||||
return bytes.joinToString("") { "%02x".format(it) }
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,9 @@ class PayuQrRequest(
|
||||
@Column(name = "response_payload", columnDefinition = "text")
|
||||
var responsePayload: String? = null,
|
||||
|
||||
@Column(name = "expiry_at", columnDefinition = "timestamptz")
|
||||
var expiryAt: OffsetDateTime? = null,
|
||||
|
||||
@Column(name = "created_at", nullable = false, columnDefinition = "timestamptz")
|
||||
val createdAt: OffsetDateTime = OffsetDateTime.now()
|
||||
)
|
||||
|
||||
@@ -6,4 +6,10 @@ import java.util.UUID
|
||||
|
||||
interface PayuQrRequestRepo : JpaRepository<PayuQrRequest, UUID> {
|
||||
fun findByBookingId(bookingId: UUID): List<PayuQrRequest>
|
||||
fun findTopByBookingIdAndAmountAndCurrencyAndStatusOrderByCreatedAtDesc(
|
||||
bookingId: UUID,
|
||||
amount: Long,
|
||||
currency: String,
|
||||
status: com.android.trisolarisserver.models.payment.PayuQrStatus
|
||||
): PayuQrRequest?
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user